Browse Source

enhance priv2pub

release/v0.1
jl777 9 years ago
parent
commit
aaef45e16f
  1. 12
      iguana/SuperNET.c
  2. 2
      iguana/SuperNET.h
  3. 126
      iguana/exchanges/bitcoin.c
  4. 23
      iguana/exchanges/bitcoin.h
  5. 2
      iguana/exchanges/nxtae.c
  6. 17
      iguana/exchanges777.h
  7. 5
      iguana/iguana777.h
  8. 169
      iguana/iguana_instantdex.c
  9. 1332
      iguana/swaps/bips_bip-atom.mediawiki at bip4x · TierNolan_bips.html
  10. BIN
      iguana/swaps/bips_bip-atom.mediawiki at bip4x · TierNolan_bips_files/5962559
  11. BIN
      iguana/swaps/bips_bip-atom.mediawiki at bip4x · TierNolan_bips_files/884931
  12. BIN
      iguana/swaps/bips_bip-atom.mediawiki at bip4x · TierNolan_bips_files/884931(1)
  13. 7
      iguana/swaps/bips_bip-atom.mediawiki at bip4x · TierNolan_bips_files/frameworks-ee521b8e9facac68ff27e93fc3ae0f8ed811d7bf9e434e84f4b9ea227780b084.js
  14. 13
      iguana/swaps/bips_bip-atom.mediawiki at bip4x · TierNolan_bips_files/github-696336964b7c42e4c6f4dfbaf1f8e57f425cd9a9d18a12f3fe6e3dd744fd7d13.js
  15. 2
      iguana/swaps/bips_bip-atom.mediawiki at bip4x · TierNolan_bips_files/github-e3dd2ae433414e240167f740f90ff2599e28804648787933de7c0183fae81c29.css
  16. 2
      iguana/swaps/bips_bip-atom.mediawiki at bip4x · TierNolan_bips_files/github2-fd8d48abb9063f51f186b0da98caa88d32b7ca8baecaa10d8a91c18a6f129b7f.css
  17. BIN
      iguana/swaps/bips_bip-atom.mediawiki at bip4x · TierNolan_bips_files/octocat-spinner-128.gif
  18. BIN
      iguana/swaps/bips_bip-atom.mediawiki at bip4x · TierNolan_bips_files/octocat-spinner-32.gif
  19. 2
      iguana/swaps/iguana_ALTswap.c
  20. 257
      iguana/swaps/iguana_BTCswap.c
  21. 2
      iguana/swaps/iguana_NXTswap.c
  22. 2
      iguana/swaps/iguana_PAXswap.c
  23. 2
      includes/iguana_apideclares.h

12
iguana/SuperNET.c

@ -919,14 +919,18 @@ cJSON *SuperNET_rosettajson(bits256 privkey,int32_t showprivs)
#include "../includes/iguana_apidefs.h"
HASH_ARG(SuperNET,priv2pub,privkey)
HASH_AND_INT(SuperNET,priv2pub,privkey,addrtype)
{
cJSON *retjson; bits256 pubkey;
cJSON *retjson; bits256 pub; uint8_t pubkey[33]; char coinaddr[64];
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
retjson = cJSON_CreateObject();
crypto_box_priv2pub(pubkey.bytes,privkey.bytes);
jaddbits256(retjson,"result",pubkey);
crypto_box_priv2pub(pub.bytes,privkey.bytes);
jaddbits256(retjson,"curve25519",pub);
pub = bitcoin_pubkey33(pubkey,privkey);
jaddbits256(retjson,"secp256k1",pub);
bitcoin_address(coinaddr,addrtype,pubkey,33);
jaddstr(retjson,"result",coinaddr);
return(jprint(retjson,1));
}

2
iguana/SuperNET.h

@ -166,6 +166,8 @@ char *SuperNET_keysinit(struct supernet_info *myinfo,char *jsonstr);
double instantdex_aveprice(struct supernet_info *myinfo,struct exchange_quote *sortbuf,int32_t max,double *totalvolp,char *base,char *rel,double volume,cJSON *argjson);
void SuperNET_setkeys(struct supernet_info *myinfo,void *pass,int32_t passlen,int32_t dosha256);
char *InstantDEX_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *remoteaddr);
bits256 bitcoin_pubkey33(uint8_t data[33],bits256 privkey);
char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey,int32_t len);
#endif

126
iguana/exchanges/bitcoin.c

@ -169,6 +169,7 @@ int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr
if ( (buf[len - 4]&0xff) == hash.bytes[31] && (buf[len - 3]&0xff) == hash.bytes[30] &&(buf[len - 2]&0xff) == hash.bytes[29] &&(buf[len - 1]&0xff) == hash.bytes[28] )
{
//printf("coinaddr.(%s) valid checksum\n",coinaddr);
return(20);
}
else
{
@ -178,7 +179,6 @@ int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr
printf("%02x ",buf[i]);
char str[65]; printf("\nhex.(%s) checkhash.(%s) len.%d mismatch %02x %02x %02x %02x vs %02x %02x %02x %02x (%s)\n",hexaddr,coinaddr,len,buf[len - 4]&0xff,buf[len - 3]&0xff,buf[len - 2]&0xff,buf[len - 1]&0xff,hash.bytes[31],hash.bytes[30],hash.bytes[29],hash.bytes[28],bits256_str(str,hash));
}
return(20);
}
return(0);
}
@ -209,6 +209,20 @@ char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey,int32_t le
return(coinaddr);
}
int32_t bitcoin_validaddress(struct iguana_info *coin,char *coinaddr)
{
uint8_t rmd160[20],addrtype;
if ( coin == 0 || coinaddr == 0 || coinaddr[0] == 0 )
return(-1);
else if ( bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr) < 0 )
return(-1);
else if ( addrtype != coin->chain->pubtype && addrtype != coin->chain->p2shtype )
return(-1);
else if ( bitcoin_address(coinaddr,addrtype,rmd160,sizeof(rmd160)) != coinaddr )
return(-1);
return(0);
}
EC_KEY *bitcoin_privkeyset(uint8_t *oddevenp,bits256 *pubkeyp,bits256 privkey)
{
BIGNUM *bn; BN_CTX *ctx = NULL; uint8_t *ptr,tmp[33]; EC_POINT *pub_key = NULL; const EC_GROUP *group;
@ -241,7 +255,7 @@ EC_KEY *bitcoin_privkeyset(uint8_t *oddevenp,bits256 *pubkeyp,bits256 privkey)
return(KEY);
}
bits256 bitcoin_pubkey(uint8_t *data,bits256 privkey)
bits256 bitcoin_pubkey33(uint8_t *data,bits256 privkey)
{
uint8_t oddeven; bits256 pubkey;
EC_KEY *KEY;
@ -254,6 +268,39 @@ bits256 bitcoin_pubkey(uint8_t *data,bits256 privkey)
return(pubkey);
}
/*int32_t bitcoin_priv2wif(char *wifstr,uint8_t privkey[32],uint8_t addrtype)
{
uint8_t tmp[128]; char hexstr[67]; cstring *btc_addr;
memcpy(tmp,privkey,32);
tmp[32] = 1;
init_hexbytes_noT(hexstr,tmp,32);
if ( (btc_addr= base58_encode_check(addrtype,true,tmp,33)) != 0 )
{
strcpy(wifstr,btc_addr->str);
cstr_free(btc_addr,true);
}
printf("-> (%s) -> wif.(%s) addrtype.%02x\n",hexstr,wifstr,addrtype);
return(0);
}
int32_t bitcoin_wif2priv(uint8_t *addrtypep,uint8_t privkey[32],char *wifstr)
{
cstring *cstr; int32_t len = -1;
if ( (cstr= base58_decode_check(addrtypep,(const char *)wifstr)) != 0 )
{
init_hexbytes_noT((void *)privkey,(void *)cstr->str,cstr->len);
if ( cstr->str[cstr->len-1] == 0x01 )
cstr->len--;
memcpy(privkey,cstr->str,cstr->len);
len = (int32_t)cstr->len;
char tmp[138];
btc_priv2wif(tmp,privkey,*addrtypep);
printf("addrtype.%02x wifstr.(%llx) len.%d\n",*addrtypep,*(long long *)privkey,len);
cstr_free(cstr,true);
}
return(len);
}*/
int32_t bitcoin_sign(uint8_t *sig,int32_t maxlen,uint8_t *data,int32_t datalen,bits256 privkey)
{
uint32_t siglen; EC_KEY *KEY; uint8_t oddeven; bits256 pubkey; int32_t retval = -1;
@ -324,6 +371,14 @@ int32_t bitcoin_p2shspend(uint8_t *script,int32_t n,uint8_t rmd160[20])
return(n);
}
int32_t bitcoin_revealsecret160(uint8_t *script,int32_t n,uint8_t secret160[20])
{
script[n++] = SCRIPT_OP_HASH160;
script[n++] = 0x14; memcpy(&script[n],secret160,0x14); n += 0x14;
script[n++] = SCRIPT_OP_EQUALVERIFY;
return(n);
}
int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20])
{
script[n++] = SCRIPT_OP_DUP;
@ -378,6 +433,32 @@ int32_t bitcoin_p2shscript(uint8_t *script,int32_t n,const uint8_t *p2shscript,c
return(n);
}
int32_t bitcoin_changescript(struct iguana_info *coin,uint8_t *changescript,int32_t n,uint64_t *changep,char *changeaddr,uint64_t inputsatoshis,uint64_t satoshis,uint64_t txfee)
{
uint8_t addrtype,rmd160[20]; int32_t len;
*changep = 0;
if ( inputsatoshis >= (satoshis + txfee) )
{
*changep = inputsatoshis - (satoshis + txfee);
if ( changeaddr != 0 && changeaddr[0] != 0 )
{
bitcoin_addr2rmd160(&addrtype,rmd160,changeaddr);
if ( addrtype == coin->chain->pubtype )
len = bitcoin_standardspend(changescript,0,rmd160);
else if ( addrtype == coin->chain->p2shtype )
len = bitcoin_standardspend(changescript,0,rmd160);
else
{
printf("error with mismatched addrtype.%02x vs (%02x %02x)\n",addrtype,coin->chain->pubtype,coin->chain->p2shtype);
return(-1);
}
return(len);
}
else printf("error no change address when there is change\n");
}
return(-1);
}
int32_t bitcoin_scriptsig(uint8_t *script,int32_t n,const struct vin_info *vp)
{
int32_t i,siglen;
@ -396,20 +477,21 @@ int32_t bitcoin_scriptsig(uint8_t *script,int32_t n,const struct vin_info *vp)
return(n);
}
int32_t bitcoin_cltvscript(uint8_t p2shtype,char *ps2h_coinaddr,uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,char *senderaddr,char *destaddr,uint32_t locktime)
int32_t bitcoin_cltvscript(uint8_t p2shtype,char *ps2h_coinaddr,uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,char *senderaddr,char *otheraddr,uint8_t secret160[20],uint32_t locktime)
{
// OP_IF
// <timestamp> OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 <hash160> OP_EQUALVERIFY OP_CHECKSIG
// OP_ELSE
// OP_DUP OP_HASH160 <hash160> OP_EQUALVERIFY OP_CHECKSIG // standard spend
// OP_HASH160 secret160 OP_EQUALVERIFY OP_DUP OP_HASH160 <hash160> OP_EQUALVERIFY OP_CHECKSIG // standard spend
// OP_ENDIF
uint8_t sha256[32],rmd160A[20],rmd160B[20],addrtypeA,addrtypeB;
bitcoin_addr2rmd160(&addrtypeA,rmd160A,senderaddr);
bitcoin_addr2rmd160(&addrtypeB,rmd160B,destaddr);
bitcoin_addr2rmd160(&addrtypeB,rmd160B,otheraddr);
script[n++] = SCRIPT_OP_IF;
n = bitcoin_checklocktimeverify(script,n,locktime);
n = bitcoin_standardspend(script,n,rmd160A);
script[n++] = SCRIPT_OP_ELSE;
n = bitcoin_revealsecret160(script,n,secret160);
n = bitcoin_standardspend(script,n,rmd160B);
script[n++] = SCRIPT_OP_ENDIF;
vcalc_sha256(0,sha256,script,n);
@ -1157,11 +1239,10 @@ char *bitcoin_json2hex(struct iguana_info *coin,bits256 *txidp,cJSON *txjson)
return(txbytes);
}
cJSON *bitcoin_createtx(struct iguana_info *coin,int32_t lockduration)
cJSON *bitcoin_createtx(struct iguana_info *coin,int32_t locktime)
{
uint32_t timestamp; cJSON *json = cJSON_CreateObject();
timestamp = (uint32_t)time(NULL) + 5;
if ( lockduration == 0 )
cJSON *json = cJSON_CreateObject();
if ( locktime == 0 )
{
jaddnum(json,"version",1);
jaddnum(json,"locktime",0);
@ -1169,20 +1250,20 @@ cJSON *bitcoin_createtx(struct iguana_info *coin,int32_t lockduration)
else
{
jaddnum(json,"version",4);
jaddnum(json,"locktime",timestamp + lockduration);
jaddnum(json,"locktime",locktime);
}
if ( coin->chain->hastimestamp != 0 )
jaddnum(json,"timestamp",timestamp);
jaddnum(json,"timestamp",time(NULL));
jadd(json,"vin",cJSON_CreateArray());
jadd(json,"vout",cJSON_CreateArray());
return(json);
}
cJSON *bitcoin_addoutput(struct iguana_info *coin,cJSON *txobj,uint8_t *paymentscript,int32_t len,double amount)
cJSON *bitcoin_addoutput(struct iguana_info *coin,cJSON *txobj,uint8_t *paymentscript,int32_t len,uint64_t satoshis)
{
char *hexstr; cJSON *item,*skey,*vouts = jduplicate(jobj(txobj,"vout"));
item = cJSON_CreateObject();
jaddnum(item,"value",amount);
jaddnum(item,"value",dstr(satoshis));
skey = cJSON_CreateObject();
hexstr = malloc(len*2 + 1);
init_hexbytes_noT(hexstr,paymentscript,len);
@ -1206,18 +1287,17 @@ cJSON *bitcoin_addinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32
return(txobj);
}
char *bitcoin_cltvtx(struct iguana_info *coin,char *changeaddr,char *senderaddr,char *destaddr,int32_t duration,double amount,bits256 txid,int32_t vout,uint64_t inputsatoshis,bits256 privkey)
char *bitcoin_cltvtx(struct iguana_info *coin,char *changeaddr,char *senderaddr,char *senders_otheraddr,char *otheraddr,uint32_t locktime,uint64_t satoshis,bits256 txid,int32_t vout,uint64_t inputsatoshis,bits256 privkey)
{
uint64_t change,satoshis; char *rawtxstr,*signedtx; struct vin_info V; bits256 cltxid,signedtxid;
int32_t cltvlen,len; uint32_t timestamp,locktime; char ps2h_coinaddr[65]; cJSON *txobj;
uint8_t p2sh_rmd160[20],cltvscript[1024],paymentscript[64],rmd160[20],addrtype;
uint64_t change; char *rawtxstr,*signedtx; struct vin_info V; bits256 cltxid,signedtxid;
int32_t cltvlen,len; uint32_t timestamp; char ps2h_coinaddr[65]; cJSON *txobj;
uint8_t p2sh_rmd160[20],cltvscript[1024],paymentscript[64],rmd160[20],secret160[20],addrtype;
timestamp = (uint32_t)time(NULL);
locktime = timestamp + duration;
cltvlen = bitcoin_cltvscript(coin->chain->p2shtype,ps2h_coinaddr,p2sh_rmd160,cltvscript,0,senderaddr,destaddr,locktime);
txobj = bitcoin_createtx(coin,duration);
bitcoin_addr2rmd160(&addrtype,secret160,senders_otheraddr);
cltvlen = bitcoin_cltvscript(coin->chain->p2shtype,ps2h_coinaddr,p2sh_rmd160,cltvscript,0,senderaddr,otheraddr,secret160,locktime);
txobj = bitcoin_createtx(coin,locktime);
len = bitcoin_p2shspend(paymentscript,0,p2sh_rmd160);
satoshis = (amount * SATOSHIDEN);
bitcoin_addoutput(coin,txobj,paymentscript,len,amount);
bitcoin_addoutput(coin,txobj,paymentscript,len,satoshis);
bitcoin_addinput(coin,txobj,txid,vout,locktime);
if ( inputsatoshis > (satoshis + 10000) )
{
@ -1435,7 +1515,7 @@ uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,cha
jaddnum(json,"volume",volume);
if ( (other= iguana_coinfind(base)) != 0 )
{
bitcoin_pubkey(pubkey,myinfo->persistent_priv);
bitcoin_pubkey33(pubkey,myinfo->persistent_priv);
bitcoin_address(coinaddr,other->chain->pubtype,pubkey,sizeof(pubkey));
jaddstr(argjson,base,coinaddr);
}

23
iguana/exchanges/bitcoin.h

@ -13,6 +13,9 @@
* *
******************************************************************************/
#ifndef H_BITCOIN_H
#define H_BITCOIN_H
#include "../../includes/openssl/ec.h"
#include "../../includes/openssl/ecdsa.h"
#include "../../includes/openssl/obj_mac.h"
@ -41,3 +44,23 @@
#define OP_CHECKLOCKTIMEVERIFY 0xb1
struct bp_key { EC_KEY *k; };
int32_t bitcoin_validaddress(struct iguana_info *coin,char *coinaddr);
int32_t bitcoin_cltvscript(uint8_t p2shtype,char *ps2h_coinaddr,uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,char *senderaddr,char *otheraddr,uint8_t secret160[20],uint32_t locktime);
int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr);
char *bitcoin_cltvtx(struct iguana_info *coin,char *changeaddr,char *senderaddr,char *senders_otheraddr,char *otheraddr,uint32_t locktime,uint64_t satoshis,bits256 txid,int32_t vout,uint64_t inputsatoshis,bits256 privkey);
int32_t bitcoin_MofNspendscript(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,const struct vin_info *vp);
cJSON *bitcoin_createtx(struct iguana_info *coin,int32_t locktime);
cJSON *bitcoin_addoutput(struct iguana_info *coin,cJSON *txobj,uint8_t *paymentscript,int32_t len,uint64_t satoshis);
int32_t bitcoin_changescript(struct iguana_info *coin,uint8_t *changescript,int32_t n,uint64_t *changep,char *changeaddr,uint64_t inputsatoshis,uint64_t satoshis,uint64_t txfee);
cJSON *bitcoin_addinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequence);
int32_t bitcoin_verifytx(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,char *rawtxstr,struct vin_info *V);
char *bitcoin_json2hex(struct iguana_info *coin,bits256 *txidp,cJSON *txjson);
int32_t bitcoin_pubkeyspend(uint8_t *script,int32_t n,uint8_t pubkey[66]);
int32_t bitcoin_p2shspend(uint8_t *script,int32_t n,uint8_t rmd160[20]);
int32_t bitcoin_revealsecret160(uint8_t *script,int32_t n,uint8_t secret160[20]);
int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20]);
#endif

2
iguana/exchanges/nxtae.c

@ -700,7 +700,7 @@ uint64_t submit_triggered_nxtae(struct supernet_info *myinfo,int32_t dotrade,cha
else sprintf(cmd+strlen(cmd),"&priceNQT=%llu",(long long)NXTprice);
}
if ( otherNXT != 0 )
sprintf(cmd+strlen(cmd),"&recipient=%llu",(long long)otherNXT);
sprintf(cmd+strlen(cmd),"&recipient=%s",otherNXT);
if ( refhash != 0 )
sprintf(cmd+strlen(cmd),"&referencedTransactionFullHash=%s",refhash);
if ( triggerhash != 0 && triggerhash[0] != 0 )

17
iguana/exchanges777.h

@ -89,12 +89,21 @@ struct exchange_request
struct exchange_quote bidasks[];
};
struct instantdex_entry { char base[24],rel[24]; double price,basevolume,pendingvolume; uint32_t expiration,nonce; char myside,acceptdir; };
struct instantdex_accept { struct queueitem DL; uint64_t orderid; uint32_t dead; struct instantdex_entry A; };
struct bitcoin_unspent { bits256 txid,privkey; uint64_t value; int32_t vout; };
struct bitcoin_spend
{
char changeaddr[64];
int32_t numinputs;
uint64_t txfee,input_satoshis,satoshis;
struct bitcoin_unspent inputs[];
};
struct instantdex_entry { char base[24],rel[24]; uint64_t price64,basevolume64,offer64; uint32_t expiration,nonce; char myside,acceptdir; };
struct instantdex_accept { struct queueitem DL; uint64_t pendingvolume64,orderid; uint32_t dead; struct instantdex_entry A; };
struct instantdex_accept *instantdex_acceptablefind(struct exchange_info *exchange,cJSON *bids,cJSON *asks,uint64_t orderid,char *base,char *rel);
cJSON *instantdex_acceptjson(struct instantdex_accept *ap);
struct instantdex_accept *instantdex_acceptable(struct exchange_info *exchange,char *base,char *rel,char *offerside,int32_t offerdir,double offerprice,double volume);
struct instantdex_accept *instantdex_acceptable(struct exchange_info *exchange,struct instantdex_accept *A,uint64_t offerbits);
void *curl_post(void **cHandlep,char *url,char *userpass,char *postfields,char *hdr0,char *hdr1,char *hdr2,char *hdr3);
char *instantdex_sendcmd(struct supernet_info *myinfo,cJSON *argjson,char *cmdstr,char *ipaddr,int32_t hops);
@ -113,7 +122,5 @@ double fxcm_price(struct exchange_info *exchange,char *base,char *rel,struct exc
double instaforex_price(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert);
char *instantdex_queueaccept(struct exchange_info *exchange,char *base,char *rel,double price,double basevolume,int32_t acceptdir,char *myside,int32_t duration);
bits256 bitcoin_pubkey(uint8_t *data,bits256 privkey);
char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey,int32_t len);
#endif

5
iguana/iguana777.h

@ -739,11 +739,10 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t rwflag,cJSON *json,uint8
int32_t iguana_ramtxbytes(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,bits256 *txidp,struct iguana_txid *tx,int32_t height,struct iguana_msgvin *vins,struct iguana_msgvout *vouts);
cJSON *bitcoin_txtest(struct iguana_info *coin,char *rawtxstr,bits256 txid);
cJSON *iguana_blockjson(struct iguana_info *coin,struct iguana_block *block,int32_t txidsflag);
int32_t iguana_sig(uint8_t *sig,int32_t maxsize,uint8_t *data,int32_t datalen,bits256 privkey);
int32_t iguana_ver(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen,bits256 pubkey);
//int32_t iguana_sig(uint8_t *sig,int32_t maxsize,uint8_t *data,int32_t datalen,bits256 privkey);
//int32_t iguana_ver(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen,bits256 pubkey);
//int32_t iguana_ver(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen,uint8_t *pubkey);
extern queue_t bundlesQ;
#include "../includes/iguana_api.h"

169
iguana/iguana_instantdex.c

@ -215,10 +215,10 @@ int32_t instantdex_bidaskdir(struct instantdex_accept *ap)
cJSON *instantdex_acceptjson(struct instantdex_accept *ap)
{
int32_t dir; struct supernet_info *myinfo = SuperNET_MYINFO(0);
int32_t dir;
cJSON *item = cJSON_CreateObject();
jadd64bits(item,"orderid",ap->orderid);
jadd64bits(item,"offerNXT",myinfo->myaddr.nxt64bits);
jadd64bits(item,"offerer",ap->A.offer64);
if ( ap->dead != 0 )
jadd64bits(item,"dead",ap->dead);
if ( (dir= instantdex_bidaskdir(ap)) > 0 )
@ -234,9 +234,10 @@ cJSON *instantdex_acceptjson(struct instantdex_accept *ap)
jaddstr(item,"base",ap->A.base);
jaddstr(item,"rel",ap->A.rel);
jaddnum(item,"timestamp",ap->A.expiration);
jaddnum(item,"price",ap->A.price);
jaddnum(item,"volume",ap->A.basevolume);
jaddnum(item,"pendingvolume",ap->A.pendingvolume);
jaddnum(item,"price",dstr(ap->A.price64));
jaddnum(item,"volume",dstr(ap->A.basevolume64));
jaddnum(item,"nonce",ap->A.nonce);
jaddnum(item,"pendingvolume",dstr(ap->pendingvolume64));
jaddnum(item,"expiresin",ap->A.expiration - time(NULL));
return(item);
}
@ -272,23 +273,26 @@ struct instantdex_accept *instantdex_acceptablefind(struct exchange_info *exchan
return(retap);
}
struct instantdex_accept *instantdex_acceptable(struct exchange_info *exchange,char *base,char *rel,char *offerside,int32_t offerdir,double offerprice,double volume)
struct instantdex_accept *instantdex_acceptable(struct exchange_info *exchange,struct instantdex_accept *A,uint64_t offerbits)
{
struct instantdex_accept PAD,*ap,*retap = 0; double bestprice = 0.; uint32_t now;
struct instantdex_accept PAD,*ap,*retap = 0; uint64_t bestprice64 = 0;
uint32_t now; int32_t offerdir;
now = (uint32_t)time(NULL);
memset(&PAD,0,sizeof(PAD));
queue_enqueue("acceptableQ",&exchange->acceptableQ,&PAD.DL,0);
offerdir = instantdex_bidaskdir(A);
while ( (ap= queue_dequeue(&exchange->acceptableQ,0)) != 0 && ap != &PAD )
{
if ( now < ap->A.expiration && ap->dead == 0 )
{
if ( volume > 0. && (strcmp(base,"*") == 0 || strcmp(base,ap->A.base) == 0) && (strcmp(rel,"*") == 0 || strcmp(rel,ap->A.rel) == 0) && volume <= (ap->A.basevolume - ap->A.pendingvolume) && offerdir*instantdex_bidaskdir(ap) < 0 )
if ( (offerbits == 0 || offerbits != A->A.offer64) && A->A.basevolume64 > 0. && (strcmp(A->A.base,"*") == 0 || strcmp(A->A.base,ap->A.base) == 0) && (strcmp(A->A.rel,"*") == 0 || strcmp(A->A.rel,ap->A.rel) == 0) && A->A.basevolume64 <= (ap->A.basevolume64 - ap->pendingvolume64) && offerdir*instantdex_bidaskdir(ap) < 0 )
{
if ( offerdir == 0 || offerprice == 0. || ((offerdir > 0 && ap->A.price > offerprice) || (offerdir < 0 && ap->A.price < offerprice)) )
if ( offerdir == 0 || A->A.price64 == 0 || ((offerdir > 0 && ap->A.price64 > A->A.price64) || (offerdir < 0 && ap->A.price64 < A->A.price64)) )
{
if ( (offerdir < 0 && ap->A.price < bestprice) || (offerdir > 0 && ap->A.price > bestprice) )
if ( bestprice64 == 0 || (offerdir < 0 && ap->A.price64 < bestprice64) || (offerdir > 0 && ap->A.price64 > bestprice64) )
{
bestprice = ap->A.price;
printf("found better price %f vs %f\n",dstr(ap->A.price64),dstr(bestprice64));
bestprice64 = ap->A.price64;
retap = ap;
}
}
@ -311,6 +315,64 @@ struct instantdex_accept *instantdex_acceptable(struct exchange_info *exchange,c
// NXT node verifies bitcoin txbytes has proper payment and cashes in with onetimepubkey
// BTC* node approves phased tx with onetimepubkey
int32_t instantdex_acceptextract(struct instantdex_accept *ap,cJSON *argjson)
{
char *base,*rel; bits256 hash;
memset(ap,0,sizeof(*ap));
if ( (base= jstr(argjson,"b")) != 0 )
safecopy(ap->A.base,base,sizeof(ap->A.base));
if ( (rel= jstr(argjson,"r")) != 0 )
safecopy(ap->A.rel,rel,sizeof(ap->A.rel));
ap->A.nonce = juint(argjson,"n");
ap->A.expiration = juint(argjson,"e");
ap->A.myside = juint(argjson,"s");
ap->A.acceptdir = jint(argjson,"d");
ap->A.offer64 = j64bits(argjson,"o");
ap->A.price64 = j64bits(argjson,"p");
ap->A.basevolume64 = j64bits(argjson,"v");
vcalc_sha256(0,hash.bytes,(void *)&ap->A,sizeof(ap->A));
ap->orderid = j64bits(argjson,"i");
if ( hash.txid != ap->orderid )
{
printf("instantdex_acceptset warning %llu != %llu\n",(long long)hash.txid,(long long)ap->orderid);
return(-1);
}
return(0);
}
bits256 instantdex_acceptset(struct instantdex_accept *ap,char *base,char *rel,int32_t duration,int32_t myside,int32_t acceptdir,double price,double volume,uint64_t offerbits)
{
bits256 hash;
memset(ap,0,sizeof(*ap));
safecopy(ap->A.base,base,sizeof(ap->A.base));
safecopy(ap->A.rel,base,sizeof(ap->A.rel));
OS_randombytes((uint8_t *)&ap->A.nonce,sizeof(ap->A.nonce));
ap->A.expiration = (uint32_t)time(NULL) + duration;
ap->A.offer64 = offerbits;
ap->A.myside = myside;
ap->A.acceptdir = acceptdir;
ap->A.price64 = price * SATOSHIDEN;
ap->A.basevolume64 = volume * SATOSHIDEN;
vcalc_sha256(0,hash.bytes,(void *)&ap->A,sizeof(ap->A));
ap->orderid = hash.txid;
return(hash);
}
cJSON *instantdex_acceptsendjson(struct instantdex_accept *ap)
{
cJSON *json = cJSON_CreateObject();
jaddstr(json,"b",ap->A.base);
jaddstr(json,"r",ap->A.rel);
jaddnum(json,"n",ap->A.nonce);
jaddnum(json,"e",ap->A.expiration);
jaddnum(json,"s",ap->A.myside);
jaddnum(json,"d",ap->A.acceptdir);
jadd64bits(json,"p",ap->A.price64);
jadd64bits(json,"v",ap->A.basevolume64);
jadd64bits(json,"i",ap->orderid);
return(json);
}
#include "swaps/iguana_BTCswap.c"
#include "swaps/iguana_ALTswap.c"
#include "swaps/iguana_NXTswap.c"
@ -318,23 +380,32 @@ struct instantdex_accept *instantdex_acceptable(struct exchange_info *exchange,c
char *instantdex_parse(struct supernet_info *myinfo,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen)
{
char cmdstr[16],*traderip; struct exchange_info *exchange = exchanges777_find("bitcoin");
char cmdstr[16],*traderip,*orderidstr; struct exchange_info *exchange; uint64_t orderid;
struct instantdex_accept A,*ap;
exchange = exchanges777_find("bitcoin");
memset(cmdstr,0,sizeof(cmdstr)), memcpy(cmdstr,msg->cmd,sizeof(msg->cmd));
if ( argjson != 0 )
{
memset(&A,0,sizeof(A));
if ( (traderip= jstr(argjson,"traderip")) != 0 && strcmp(traderip,myinfo->ipaddr) == 0 )
{
printf("got my own request\n");
return(clonestr("{\"result\":\"got my own request\"}"));
}
if ( (orderidstr= jstr(argjson,"id")) != 0 )
{
orderid = calc_nxt64bits(orderidstr);
if ( (ap= instantdex_acceptablefind(exchange,0,0,orderid,"*","*")) != 0 )
A = *ap;
} else instantdex_acceptextract(&A,argjson);
if ( strncmp(cmdstr,"BTC",3) == 0 )
return(instantdex_BTCswap(myinfo,exchange,cmdstr+3,msg,argjson,remoteaddr,signerbits,data,datalen));
return(instantdex_BTCswap(myinfo,exchange,&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,data,datalen));
else if ( strncmp(cmdstr,"NXT",3) == 0 )
return(instantdex_NXTswap(myinfo,exchange,cmdstr+3,msg,argjson,remoteaddr,signerbits,data,datalen));
return(instantdex_NXTswap(myinfo,exchange,&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,data,datalen));
else if ( strncmp(cmdstr,"ALT",3) == 0 )
return(instantdex_ALTswap(myinfo,exchange,cmdstr+3,msg,argjson,remoteaddr,signerbits,data,datalen));
return(instantdex_ALTswap(myinfo,exchange,&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,data,datalen));
else if ( strncmp(cmdstr,"PAX",3) == 0 )
return(instantdex_PAXswap(myinfo,exchanges777_find("PAX"),cmdstr+3,msg,argjson,remoteaddr,signerbits,data,datalen));
return(instantdex_PAXswap(myinfo,exchanges777_find("PAX"),&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,data,datalen));
else return(clonestr("{\"error\":\"unrecognized atomic swap family\"}"));
}
return(clonestr("{\"error\":\"request needs argjson\"}"));
@ -387,25 +458,18 @@ char *InstantDEX_hexmsg(struct supernet_info *myinfo,void *ptr,int32_t len,char
return(retstr);
}
char *instantdex_queueaccept(struct exchange_info *exchange,char *base,char *rel,double price,double basevolume,int32_t acceptdir,char *myside,int32_t duration)
char *instantdex_queueaccept(struct exchange_info *exchange,char *base,char *rel,double price,double basevolume,int32_t acceptdir,char *mysidestr,int32_t duration)
{
struct instantdex_accept *ap; bits256 hash;
struct instantdex_accept *ap; int32_t myside; struct supernet_info *myinfo = SuperNET_MYINFO(0);
if ( exchange != 0 )
{
ap = calloc(1,sizeof(*ap));
OS_randombytes((uint8_t *)&ap->A.nonce,sizeof(ap->A.nonce));
safecopy(ap->A.base,base,sizeof(ap->A.base));
safecopy(ap->A.rel,rel,sizeof(ap->A.rel));
if ( strcmp(myside,base) == 0 )
ap->A.myside = 0;
else if ( strcmp(myside,rel) == 0 )
ap->A.myside = 1;
else ap->A.myside = -1;
ap->A.acceptdir = acceptdir;
ap->A.price = price, ap->A.basevolume = basevolume;
ap->A.expiration = (uint32_t)time(NULL) + duration;
vcalc_sha256(0,hash.bytes,(void *)&ap->A,sizeof(ap->A));
ap->orderid = hash.txid;
if ( strcmp(mysidestr,base) == 0 )
myside = 0;
else if ( strcmp(mysidestr,rel) == 0 )
myside = 1;
else myside = -1;
instantdex_acceptset(ap,base,rel,duration,myside,acceptdir,price,basevolume,myinfo->myaddr.nxt64bits);
queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0);
return(jprint(instantdex_acceptjson(ap),1));
}
@ -430,48 +494,24 @@ TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,minaccept,base,rel,minprice,basevolume)
TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,BTCoffer,othercoin,otherassetid,maxprice,othervolume)
{
int32_t hops = INSTANTDEX_HOPS; cJSON *argjson; char *base,*str,coinaddr[64]; struct iguana_info *other;
uint8_t pubkey[33];
if ( remoteaddr == 0 )
{
argjson = cJSON_CreateObject();
base = othercoin[0] != 0 ? othercoin : otherassetid;
if ( (other= iguana_coinfind(othercoin)) != 0 )
{
bitcoin_pubkey(pubkey,myinfo->persistent_priv);
bitcoin_address(coinaddr,other->chain->pubtype,pubkey,sizeof(pubkey));
jaddstr(argjson,othercoin,coinaddr);
}
jaddstr(argjson,"base",base);
jaddstr(argjson,"rel","BTC");
jaddstr(argjson,"BTC",myinfo->myaddr.BTC);
if ( maxprice > 0. )
{
if ( (str= InstantDEX_maxaccept(IGUANA_CALLARGS,base,"BTC",maxprice,othervolume)) != 0 )
free(str);
jaddnum(argjson,"maxprice",maxprice);
}
jaddnum(argjson,"volume",othervolume);
return(instantdex_sendcmd(myinfo,argjson,"BTCoffer",myinfo->ipaddr,hops));
} else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}"));
return(instantdex_btcoffer(myinfo,exchanges777_find("bitcoin"),othercoin[0] != 0 ? othercoin : otherassetid,othervolume,maxprice));
else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}"));
}
STRING_AND_TWO_DOUBLES(InstantDEX,ALToffer,basecoin,minprice,basevolume)
{
int32_t hops = INSTANTDEX_HOPS; cJSON *argjson; char *str;
int32_t hops = INSTANTDEX_HOPS; cJSON *argjson; char *str; struct instantdex_accept A;
if ( remoteaddr == 0 )
{
argjson = cJSON_CreateObject();
if ( iguana_coinfind(basecoin) == 0 )
return(clonestr("{\"error\":\"InstantDEX basecoin is not active, need to addcoin\"}"));
jaddstr(argjson,"base",basecoin);
jaddstr(argjson,"rel","BTC");
jaddnum(argjson,"volume",basevolume);
instantdex_acceptset(&A,basecoin,"BTC",INSTANTDEX_OFFERDURATION,0,1,minprice,basevolume,myinfo->myaddr.nxt64bits);
argjson = instantdex_acceptsendjson(&A);
if ( minprice > 0. )
{
if ( (str= InstantDEX_minaccept(IGUANA_CALLARGS,basecoin,"BTC",minprice,basevolume)) != 0 )
free(str);
jaddnum(argjson,"minprice",minprice);
}
return(instantdex_sendcmd(myinfo,argjson,"ALToffer",myinfo->ipaddr,hops));
} else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}"));
@ -479,23 +519,20 @@ STRING_AND_TWO_DOUBLES(InstantDEX,ALToffer,basecoin,minprice,basevolume)
STRING_AND_TWO_DOUBLES(InstantDEX,NXToffer,assetid,minprice,basevolume)
{
int32_t hops = INSTANTDEX_HOPS; cJSON *argjson; char *base,*str;
int32_t hops = INSTANTDEX_HOPS; cJSON *argjson; char *base,*str; struct instantdex_accept A;
if ( remoteaddr == 0 )
{
argjson = cJSON_CreateObject();
if ( assetid == 0 || assetid[0] == 0 || strcmp(assetid,"0") == 0 || strcmp(assetid,"NXT") == 0 || strcmp(assetid,"nxt") == 0 )
base = "NXT";
else if ( is_decimalstr(assetid) <= 0 )
return(clonestr("{\"error\":\"InstantDEX NXToffer illegal assetid\"}"));
else base = assetid;
jaddstr(argjson,"base",base);
jaddstr(argjson,"rel","BTC");
jaddnum(argjson,"volume",basevolume);
instantdex_acceptset(&A,base,"BTC",INSTANTDEX_OFFERDURATION,0,1,minprice,basevolume,myinfo->myaddr.nxt64bits);
argjson = instantdex_acceptsendjson(&A);
if ( minprice > 0. )
{
if ( (str= InstantDEX_minaccept(IGUANA_CALLARGS,base,"BTC",minprice,basevolume)) != 0 )
free(str);
jaddnum(argjson,"minprice",minprice);
}
return(instantdex_sendcmd(myinfo,argjson,"NXToffer",myinfo->ipaddr,hops));
} else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}"));

1332
iguana/swaps/bips_bip-atom.mediawiki at bip4x · TierNolan_bips.html

File diff suppressed because it is too large

BIN
iguana/swaps/bips_bip-atom.mediawiki at bip4x · TierNolan_bips_files/5962559

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
iguana/swaps/bips_bip-atom.mediawiki at bip4x · TierNolan_bips_files/884931

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
iguana/swaps/bips_bip-atom.mediawiki at bip4x · TierNolan_bips_files/884931(1)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

7
iguana/swaps/bips_bip-atom.mediawiki at bip4x · TierNolan_bips_files/frameworks-ee521b8e9facac68ff27e93fc3ae0f8ed811d7bf9e434e84f4b9ea227780b084.js

File diff suppressed because one or more lines are too long

13
iguana/swaps/bips_bip-atom.mediawiki at bip4x · TierNolan_bips_files/github-696336964b7c42e4c6f4dfbaf1f8e57f425cd9a9d18a12f3fe6e3dd744fd7d13.js

File diff suppressed because one or more lines are too long

2
iguana/swaps/bips_bip-atom.mediawiki at bip4x · TierNolan_bips_files/github-e3dd2ae433414e240167f740f90ff2599e28804648787933de7c0183fae81c29.css

File diff suppressed because one or more lines are too long

2
iguana/swaps/bips_bip-atom.mediawiki at bip4x · TierNolan_bips_files/github2-fd8d48abb9063f51f186b0da98caa88d32b7ca8baecaa10d8a91c18a6f129b7f.css

File diff suppressed because one or more lines are too long

BIN
iguana/swaps/bips_bip-atom.mediawiki at bip4x · TierNolan_bips_files/octocat-spinner-128.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
iguana/swaps/bips_bip-atom.mediawiki at bip4x · TierNolan_bips_files/octocat-spinner-32.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

2
iguana/swaps/iguana_ALTswap.c

@ -25,7 +25,7 @@
// NXT node verifies bitcoin txbytes has proper payment and cashes in with onetimepubkey
// BTC* node approves phased tx with onetimepubkey
char *instantdex_ALTswap(struct supernet_info *myinfo,struct exchange_info *exchange,char *cmdstr,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen) // receiving side
char *instantdex_ALTswap(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,char *cmdstr,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen) // receiving side
{
char *retstr = 0;
if ( strcmp(cmdstr,"offer") == 0 )

257
iguana/swaps/iguana_BTCswap.c

@ -13,56 +13,247 @@
* *
******************************************************************************/
// BTCoffer:
// sends NXT assetid, volume and desired
// request:
// other node sends (othercoin, othercoinaddr, otherNXT and reftx that expires well before phasedtx)
// proposal:
// NXT node submits phasedtx that refers to it, but it wont confirm
// approve:
// other node verifies unconfirmed has phasedtx and broadcasts cltv, also to NXT node, releases trigger
// confirm:
// NXT node verifies bitcoin txbytes has proper payment and cashes in with onetimepubkey
// BTC* node approves phased tx with onetimepubkey
/*if ( retap != 0 )
#include "../exchanges/bitcoin.h"
// https://github.com/TierNolan/bips/blob/bip4x/bip-atom.mediawiki
uint64_t instantdex_relsatoshis(uint64_t price,uint64_t volume)
{
if ( volume > price )
return(price * dstr(volume));
else return(dstr(price) * volume);
}
bits256 instantdex_sharedpub256(uint8_t pubkey[33],bits256 privkey,bits256 hash,int32_t n)
{
bits256 tmppriv,shared,iters; int32_t i;
iters = shared = curve25519_shared(privkey,hash);
for (i=0; i<n; i++)
iters = curve25519(iters,curve25519(iters,curve25519_basepoint9()));
vcalc_sha256cat(tmppriv.bytes,shared.bytes,sizeof(shared),iters.bytes,sizeof(iters));
return(bitcoin_pubkey33(pubkey,tmppriv));
}
int32_t instantdex_pubkeyargs(cJSON *argjson,int32_t numpubs,bits256 privkey,bits256 hash,int32_t firstbyte)
{
char buf[3]; int32_t i,n; bits256 tmp; uint8_t pubkey[33];
sprintf(buf,"%c0",'A' - 0x02 + firstbyte);
for (i=n=0; i<numpubs*100&&n<numpubs; i++)
{
tmp = instantdex_sharedpub256(pubkey,privkey,hash,i+1);
if ( pubkey[0] != firstbyte )
continue;
buf[1] = '0' + n++;
jaddbits256(argjson,buf,tmp);
}
return(n);
}
int32_t bitcoin_2of2spendscript(int32_t *paymentlenp,uint8_t *paymentscript,uint8_t *msigscript,bits256 pub0,bits256 pub1)
{
struct vin_info V; uint8_t p2sh_rmd160[20]; int32_t p2shlen;
memset(&V,0,sizeof(V));
V.M = V.N = 2;
memcpy(V.signers[0].pubkey+1,pub0.bytes,sizeof(pub0)), V.signers[0].pubkey[0] = 0x02;
memcpy(V.signers[1].pubkey+1,pub1.bytes,sizeof(pub1)), V.signers[1].pubkey[0] = 0x03;
p2shlen = bitcoin_MofNspendscript(p2sh_rmd160,msigscript,0,&V);
*paymentlenp = bitcoin_p2shspend(paymentscript,0,p2sh_rmd160);
return(p2shlen);
}
/*struct bitcoin_unspent { bits256 txid,privkey; uint64_t value; int32_t vout; };
struct bitcoin_spend
{
char changeaddr[64];
int32_t numinputs;
uint64_t txfee,input_satoshis,satoshis;
struct bitcoin_unspent inputs[];
};*/
char *instantdex_bailintx(struct iguana_info *coin,bits256 *txidp,struct bitcoin_spend *spend,bits256 A0,bits256 B0,uint8_t x[20],int32_t isbob)
{
retap->A.pendingvolume -= volume;
price = retap->A.price;
/*Input value: B + 2*fb + change
Input source: (From Bob's coins, multiple inputs are allowed)
Output 0 value: B
ScriptPubKey 0: OP_HASH160 Hash160(P2SH Redeem) OP_EQUAL
Output 1 value: fb
ScriptPubKey 1: OP_HASH160 Hash160(x) OP_EQUALVERIFY pub-A1 OP_CHECKSIG
Output 2 value: change
ScriptPubKey 2: <= 100 bytes
P2SH Redeem: OP_2 pub-A1 pub-B1 OP_2 OP_CHECKMULTISIG
Name: Alice.Bail.In
Input value: A + 2*fa + change
Input source: (From Alice's altcoins, multiple inputs are allowed)
Output 0 value: A
ScriptPubKey 0: OP_HASH160 Hash160(P2SH Redeem) OP_EQUAL
Output 1 value: fa
ScriptPubKey 1: OP_HASH160 Hash160(x) OP_EQUAL
Output 2 value: change
ScriptPubKey 2: <= 100 bytes*/
uint64_t change; char *rawtxstr,*signedtx; struct vin_info *V; bits256 txid,signedtxid;
int32_t p2shlen,i; cJSON *txobj; int32_t scriptv0len,scriptv1len,scriptv2len;
uint8_t p2shscript[256],scriptv0[128],scriptv1[128],changescript[128],pubkey[35];
p2shlen = bitcoin_2of2spendscript(&scriptv0len,scriptv0,p2shscript,A0,B0);
txobj = bitcoin_createtx(coin,0);
bitcoin_addoutput(coin,txobj,scriptv0,scriptv0len,spend->satoshis);
if ( isbob != 0 )
{
scriptv1len = bitcoin_revealsecret160(scriptv1,0,x);
scriptv1len = bitcoin_pubkeyspend(scriptv1,scriptv1len,pubkey);
} else scriptv1len = bitcoin_p2shspend(scriptv1,0,x);
bitcoin_addoutput(coin,txobj,scriptv1,scriptv1len,spend->txfee);
if ( (scriptv2len= bitcoin_changescript(coin,changescript,0,&change,spend->changeaddr,spend->input_satoshis,spend->satoshis,spend->txfee)) > 0 )
bitcoin_addoutput(coin,txobj,changescript,scriptv2len,change);
for (i=0; i<spend->numinputs; i++)
bitcoin_addinput(coin,txobj,spend->inputs[i].txid,spend->inputs[i].vout,0xffffffff);
rawtxstr = bitcoin_json2hex(coin,&txid,txobj);
char str[65]; printf("%s_bailin.%s (%s)\n",isbob!=0?"bob":"alice",bits256_str(str,txid),rawtxstr);
V = calloc(spend->numinputs,sizeof(*V));
for (i=0; i<spend->numinputs; i++)
V[i].signers[0].privkey = spend->inputs[i].privkey;
bitcoin_verifytx(coin,&signedtxid,&signedtx,rawtxstr,V);
free(rawtxstr), free(V);
if ( signedtx != 0 )
printf("signed bob_bailin.%s (%s)\n",bits256_str(str,signedtxid),signedtx);
else printf("error generating signedtx\n");
free_json(txobj);
*txidp = txid;
return(signedtx);
}
struct instantdex_accept *instantdex_acceptable(struct supernet_info *myinfo,cJSON *array,char *refstr,char *base,char *rel,char *offerside,int32_t offerdir,double offerprice,double volume)
*/
char *instantdex_BTCswap(struct supernet_info *myinfo,struct exchange_info *exchange,char *cmdstr,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen) // receiving side
int32_t instantdex_calcx20(char hexstr[41],uint8_t *p2shscript,uint8_t firstbyte,bits256 pub3)
{
char *base,*rel,*offerside,*retstr = 0; int32_t offerdir = 0; struct instantdex_accept *ap; double offerprice,volume;
uint8_t pubkey[33],script[64],rmd160[20]; int32_t n; bits256 hash;
memcpy(pubkey+1,pub3.bytes,sizeof(pub3)), pubkey[0] = firstbyte;
n = bitcoin_pubkeyspend(p2shscript,0,pubkey);
vcalc_sha256(0,hash.bytes,script,n);
calc_rmd160(0,rmd160,hash.bytes,sizeof(hash.bytes));
init_hexbytes_noT(hexstr,rmd160,sizeof(rmd160));
return(n);
}
char *instantdex_btcoffer(struct supernet_info *myinfo,struct exchange_info *exchange,char *othercoin,double othervolume,double maxprice) // Bob sending to network (Alice)
{
char *str,coinaddr[64],xstr[41]; uint8_t xscript[64]; struct iguana_info *other;
struct instantdex_accept A; cJSON *newjson; bits256 hash,pub3;
if ( othercoin == 0 || (other= iguana_coinfind(othercoin)) == 0 )
return(clonestr("{\"error\":\"invalid othercoin\"}"));
hash = instantdex_acceptset(&A,othercoin,"BTC",INSTANTDEX_OFFERDURATION,1,-1,maxprice,othervolume,myinfo->myaddr.nxt64bits);
newjson = instantdex_acceptsendjson(&A);
if ( instantdex_pubkeyargs(newjson,4,myinfo->persistent_priv,hash,0x03) != 4 )
return(clonestr("{\"error\":\"highly unlikely run of 02 pubkeys\"}"));
pub3 = jbits256(newjson,"B3");
jdelete(newjson,"B3");
instantdex_calcx20(xstr,xscript,0x03,pub3);
jaddstr(newjson,"x",xstr);
if ( coinaddr[0] != 0 )
jaddstr(newjson,othercoin,coinaddr);
if ( maxprice > 0. )
{
if ( (str= InstantDEX_maxaccept(myinfo,0,newjson,0,othercoin,"BTC",maxprice,othervolume)) != 0 )
free(str);
}
return(instantdex_sendcmd(myinfo,newjson,"BTCoffer",myinfo->ipaddr,INSTANTDEX_HOPS));
}
char *instantdex_BTCswap(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,char *cmdstr,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen) // receiving side
{
uint8_t script[999],p2sh_rmd160[20],secret160[20],pubkey[36],addrtype;
bits256 hash,bailintxid,A0,B0; struct bitcoin_spend SPEND;
struct instantdex_accept *ap; uint64_t satoshis,othersatoshis,orderid;
char p2sh_coinaddr[64],*senderaddr,otheraddr[64],base[24],coinaddr[64],*retstr,*bailintx;
int32_t scriptlen,locktime,offerdir = 0; struct iguana_info *coinbtc,*other; cJSON *newjson;
retstr = 0;
memset(&SPEND,0,sizeof(SPEND));
if ( exchange == 0 )
return(clonestr("{\"error\":\"instantdex_BTCswap null exchange ptr\"}"));
if ( strcmp(cmdstr,"offer") == 0 )
offerdir = instantdex_bidaskdir(A);
if ( (other= iguana_coinfind(A->A.base)) == 0 || (coinbtc= iguana_coinfind("BTC")) == 0 )
return(clonestr("{\"error\":\"instantdex_BTCswap cant find btc or other coin info\"}"));
locktime = (uint32_t)(A->A.expiration + INSTANTDEX_OFFERDURATION);
if ( A->A.rel == 0 || strcmp(A->A.rel,"BTC") != 0 )
return(clonestr("{\"error\":\"instantdex_BTCswap offer non BTC rel\"}"));
if ( strcmp(cmdstr,"offer") == 0 ) // sender is Bob, receiver is network (Alice)
{
base = jstr(argjson,"base"), rel = jstr(argjson,"rel");
if ( rel == 0 || strcmp(rel,"BTC") != 0 )
return(clonestr("{\"error\":\"instantdex_BTCswap offer non BTC rel\"}"));
offerprice = jdouble(argjson,"price"), volume = jdouble(argjson,"volume");
offerside = "BTC";
// offerdir = xxx
// printf("got offer.(%s) offerside.%s offerdir.%d\n",jprint(argjson,0),offerside,offerdir);
if ( (ap= instantdex_acceptable(exchange,base,rel,offerside,offerdir,offerprice,volume)) != 0 )
// should add to orderbook if not accepted
if ( A->A.expiration < (time(NULL) + INSTANTDEX_DURATION) )
return(clonestr("{\"error\":\"instantdex_BTCswap offer too close to expiration\"}"));
printf("got offer.(%s) offerside.%d offerdir.%d\n",jprint(argjson,0),A->A.myside,A->A.acceptdir);
if ( (ap= instantdex_acceptable(exchange,A,myinfo->myaddr.nxt64bits)) != 0 )
{
}
ap->pendingvolume64 -= A->A.basevolume64;
satoshis = instantdex_relsatoshis(A->A.price64,A->A.basevolume64);
newjson = cJSON_CreateObject();
if ( instantdex_pubkeyargs(argjson,3,myinfo->persistent_priv,hash,0x02) != 3 )
return(clonestr("{\"error\":\"highly unlikely run of 03 pubkeys\"}"));
jadd64bits(newjson,"id",A->orderid);
jadd64bits(newjson,"BTC",satoshis);
jadd64bits(newjson,"v",A->A.basevolume64);
jaddstr(newjson,"b",other->symbol);
jaddstr(newjson,other->symbol,otheraddr);
jaddstr(newjson,"p2sh",p2sh_coinaddr);
bailintx = instantdex_bailintx(coinbtc,&bailintxid,&SPEND,A0,B0,secret160,1);
jaddstr(newjson,"bailin",bailintx);
jaddbits256(newjson,"bailintxid",bailintxid);
free(bailintx);
return(instantdex_sendcmd(myinfo,newjson,"proposal",myinfo->ipaddr,INSTANTDEX_HOPS));
} else printf("no matching trade.(%s)\n",jprint(argjson,0));
}
else if ( strcmp(cmdstr,"proposal") == 0 )
else if ( strcmp(cmdstr,"proposal") == 0 ) // sender is Alice, receiver is Bob
{
satoshis = j64bits(argjson,"BTC");
orderid = j64bits(argjson,"id");
othersatoshis = j64bits(argjson,"v");
senderaddr = myinfo->myaddr.BTC;
if ( jobj(argjson,other->symbol) != 0 )
safecopy(otheraddr,jstr(argjson,other->symbol),sizeof(otheraddr));
if ( jobj(argjson,"b") != 0 )
safecopy(base,jstr(argjson,"b"),sizeof(base));
printf("proposal orderid.%llu BTC satoshis %.8f for %s vol %.8f ps2h.%s\n",A->orderid,dstr(satoshis),base,dstr(othersatoshis),p2sh_coinaddr);
if ( A->orderid != orderid )
{
printf("orderid mismatch %llu vs %llu\n",(long long)orderid,(long long)A->orderid);
return(clonestr("{\"error\":\"instantdex_BTCswap orderid mismatch\"}"));
}
if ( senderaddr == 0 || strcmp(A->A.base,base) != 0 || strcmp(A->A.rel,"BTC") != 0 )
{
printf("senderaddr.%p base.(%s vs %s) rel.(%s vs %s)\n",senderaddr,A->A.base,base,A->A.rel,"BTC");
return(clonestr("{\"error\":\"instantdex_BTCswap base or rel mismatch\"}"));
}
bitcoin_pubkey33(pubkey,myinfo->persistent_priv);
bitcoin_address(coinaddr,other->chain->pubtype,pubkey,sizeof(pubkey));
bitcoin_addr2rmd160(&addrtype,secret160,coinaddr);
scriptlen = bitcoin_cltvscript(coinbtc->chain->p2shtype,p2sh_coinaddr,p2sh_rmd160,script,0,senderaddr,otheraddr,secret160,locktime);
if ( jobj(argjson,"p2sh") != 0 )
{
if ( strcmp(jstr(argjson,"p2sh"),p2sh_coinaddr) != 0 )
{
printf("mismatched p2sh.(%s) vs (%s)\n",jstr(argjson,"p2sh"),p2sh_coinaddr);
return(clonestr("{\"error\":\"instantdex_BTCswap base or rel mismatch\"}"));
}
}
if ( satoshis != instantdex_relsatoshis(A->A.price64,A->A.basevolume64) )
{
printf("satoshis mismatch %llu vs %llu\n",(long long)satoshis,(long long)instantdex_relsatoshis(A->A.price64,A->A.basevolume64));
return(clonestr("{\"error\":\"instantdex_BTCswap satoshis mismatch\"}"));
}
if ( othersatoshis != A->A.basevolume64 )
{
printf("othersatoshis mismatch %llu vs %llu\n",(long long)satoshis,(long long)A->A.basevolume64);
return(clonestr("{\"error\":\"instantdex_BTCswap satoshis mismatch\"}"));
}
// return(instantdex_sendcmd(myinfo,newjson,"accept",myinfo->ipaddr,INSTANTDEX_HOPS));
}
else if ( strcmp(cmdstr,"accept") == 0 )
else if ( strcmp(cmdstr,"accept") == 0 ) // sender is Bob, receiver is Alice
{
}
else if ( strcmp(cmdstr,"confirm") == 0 )
else if ( strcmp(cmdstr,"confirm") == 0 ) // both send and receive
{
}
else retstr = clonestr("{\"error\":\"BTC swap got unrecognized command\"}");
if ( retstr == 0 )
retstr = clonestr("{\"error\":\"BTC swap null retstr\"}");
return(retstr);
}

2
iguana/swaps/iguana_NXTswap.c

@ -25,7 +25,7 @@
// NXT node verifies bitcoin txbytes has proper payment and cashes in with onetimepubkey
// BTC* node approves phased tx with onetimepubkey
char *instantdex_NXTswap(struct supernet_info *myinfo,struct exchange_info *exchange,char *cmdstr,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen) // receiving side
char *instantdex_NXTswap(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,char *cmdstr,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen) // receiving side
{
char *retstr = 0;
if ( strcmp(cmdstr,"offer") == 0 )

2
iguana/swaps/iguana_PAXswap.c

@ -25,7 +25,7 @@
// NXT node verifies bitcoin txbytes has proper payment and cashes in with onetimepubkey
// BTC* node approves phased tx with onetimepubkey
char *instantdex_PAXswap(struct supernet_info *myinfo,struct exchange_info *exchange,char *cmdstr,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen) // receiving side
char *instantdex_PAXswap(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,char *cmdstr,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen) // receiving side
{
char *retstr = 0;
return(clonestr("{\"error\":\"PAX swap is not yet\"}"));

2
includes/iguana_apideclares.h

@ -92,7 +92,7 @@ TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(SuperNET,DHT,hexmsg,destip,categoryhash,sub
THREE_STRINGS(SuperNET,rosetta,passphrase,pin,showprivkey);
ZERO_ARGS(SuperNET,keypair);
HASH_ARG(SuperNET,priv2pub,privkey);
HASH_AND_INT(SuperNET,priv2pub,privkey,addrtype);
STRING_ARG(SuperNET,wif2priv,wif);
TWOHASHES_AND_STRING(SuperNET,cipher,privkey,destpubkey,message);

Loading…
Cancel
Save