Browse Source

Withdraw

etomic
jl777 7 years ago
parent
commit
009ea85c3f
  1. 15
      iguana/exchanges/LP_commands.c
  2. 1
      iguana/exchanges/LP_include.h
  3. 2
      iguana/exchanges/LP_network.c
  4. 2
      iguana/exchanges/LP_ordermatch.c
  5. 22
      iguana/exchanges/LP_rpc.c
  6. 247
      iguana/exchanges/LP_transaction.c
  7. 2
      iguana/exchanges/install
  8. 3
      iguana/exchanges/register
  9. 4
      iguana/exchanges/registerall
  10. 3
      iguana/exchanges/withdraw

15
iguana/exchanges/LP_commands.c

@ -104,9 +104,11 @@ enable(coin)\n\
disable(coin)\n\
inventory(coin)\n\
bestfit(rel, relvolume)\n\
lastnonce()\n\
buy(base, rel, price, relvolume, timeout=10, duration=3600, nonce)\n\
sell(base, rel, price, basevolume, timeout=10, duration=3600, nonce)\n\
withdraw(coin, outputs[])\n\
sendrawtransaction(coin, signedtx)\n\
swapstatus()\n\
swapstatus(requestid, quoteid)\n\
public API:\n \
@ -279,13 +281,17 @@ dividends(coin, height, <args>)\n\
return(jprint(LP_electrumserver(ptr,jstr(argjson,"ipaddr"),juint(argjson,"port")),1));
} else return(clonestr("{\"error\":\"cant find coind\"}"));
}
else if ( strcmp(method,"sendrawtransaction") == 0 )
{
return(LP_sendrawtransaction(coin,jstr(argjson,"signedtx")));
}
else if ( strcmp(method,"withdraw") == 0 )
{
if ( (ptr= LP_coinsearch(coin)) != 0 )
{
if ( jobj(argjson,"outputs") == 0 )
return(clonestr("{\"error\":\"withdraw needs to have outputs\"}"));
//else return(LP_withdraw(ptr,argjson));
else return(LP_withdraw(ptr,argjson));
}
return(clonestr("{\"error\":\"cant find coind\"}"));
}
@ -359,6 +365,13 @@ dividends(coin, height, <args>)\n\
return(basilisk_swapentry(requestid,quoteid));
else return(basilisk_swaplist(0,0));
}
else if ( strcmp(method,"lastnonce") == 0 )
{
cJSON *retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jaddnum(retjson,"lastnonce",LP_lastnonce);
return(jprint(retjson,1));
}
else if ( strcmp(method,"myprices") == 0 )
return(LP_myprices());
else if ( strcmp(method,"trust") == 0 )

1
iguana/exchanges/LP_include.h

@ -332,5 +332,6 @@ struct LP_utxoinfo *_LP_utxofind(int32_t iambob,bits256 txid,int32_t vout);
struct LP_utxoinfo *_LP_utxo2find(int32_t iambob,bits256 txid,int32_t vout);
void LP_listunspent_query(char *symbol,char *coinaddr);
int32_t bitcoin_priv2wif(uint8_t wiftaddr,char *wifstr,bits256 privkey,uint8_t addrtype);
#endif

2
iguana/exchanges/LP_network.c

@ -171,7 +171,7 @@ void queue_loop(void *ignore)
if ( duplicate > 0 )
{
LP_Qfound++;
if ( (LP_Qfound % 10) == 0 )
if ( (LP_Qfound % 100) == 0 )
printf("found.%u Q.%d err.%d match.%d\n",ptr->crc32,LP_Qenqueued,LP_Qerrors,LP_Qfound);
flag = 1;
}

2
iguana/exchanges/LP_ordermatch.c

@ -904,7 +904,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
{
if ( LP_isavailable(butxo) > 0 )
{
butxo->T.swappending = Q.timestamp + LP_RESERVETIME;
autxo->T.swappending = butxo->T.swappending = Q.timestamp + LP_RESERVETIME;
retjson = LP_quotejson(&Q);
butxo->S.otherpubkey = jbits256(argjson,"desthash");
LP_unavailableset(butxo,butxo->S.otherpubkey);

22
iguana/exchanges/LP_rpc.c

@ -419,6 +419,24 @@ int32_t LP_address_ismine(char *symbol,char *address)
return(doneflag);
}
int32_t LP_address_isvalid(char *symbol,char *address)
{
int32_t isvalid = 0; cJSON *retjson;
if ( symbol == 0 || symbol[0] == 0 )
return(0);
if ( (retjson= LP_validateaddress(symbol,address)) != 0 )
{
if ( jobj(retjson,"isvalid") != 0 && is_cJSON_True(jobj(retjson,"isvalid")) != 0 )
{
isvalid = 1;
//printf("%s ismine (%s)\n",address,jprint(retjson,0));
}
//printf("%s\n",jprint(retjson,0));
free_json(retjson);
}
return(isvalid);
}
cJSON *LP_listunspent(char *symbol,char *coinaddr)
{
char buf[128]; cJSON *retjson; struct iguana_info *coin;
@ -612,9 +630,9 @@ double LP_getestimatedrate(struct iguana_info *coin)
char *LP_sendrawtransaction(char *symbol,char *signedtx)
{
cJSON *array,*errobj; char *paramstr,*tmpstr,*retstr=0; int32_t n,alreadyflag = 0; cJSON *retjson; struct iguana_info *coin;
if ( symbol == 0 || symbol[0] == 0 )
if ( symbol == 0 || symbol[0] == 0 || signedtx == 0 || signedtx[0] == 0 )
{
printf("LP_sendrawtransaction null symbol\n");
printf("LP_sendrawtransaction null symbol %p or signedtx.%p\n",symbol,signedtx);
return(0);
}
coin = LP_coinfind(symbol);

247
iguana/exchanges/LP_transaction.c

@ -724,18 +724,244 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch
return(signedtx);
}
/*char *LP_withdraw(struct iguana_info *coin,cJSON *argjson)
int32_t LP_vin_select(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t *belowp,struct LP_address_utxo **utxos,int32_t numunspents,uint64_t value,int32_t maxmode)
{
int32_t iter,i,datalen; char changeaddr[64],*signedtx=0; cJSON *retjson; bits256 signedtxid; uint64_t txfee,newtxfee=10000;
int32_t i,abovei,belowi; int64_t above,below,gap,atx_value;
abovei = belowi = -1;
for (above=below=i=0; i<numunspents; i++)
{
if ( utxos[i] == 0 )
continue;
if ( (atx_value= utxos[i]->U.value) <= 0 )
{
//printf("illegal value.%d\n",i);
continue;
}
if ( atx_value == value )
{
*aboveip = *belowip = i;
*abovep = *belowp = 0;
return(i);
}
else if ( atx_value > value )
{
gap = (atx_value - value);
if ( above == 0 || gap < above )
{
above = gap;
abovei = i;
}
} else gap = (value - atx_value);
if ( below == 0 || gap < below )
{
below = gap;
belowi = i;
}
}
*aboveip = abovei;
*abovep = above;
*belowip = belowi;
*belowp = below;
//printf("above.%d below.%d\n",abovei,belowi);
return(abovei >= 0 && above < (below>>1) ? abovei : belowi);
}
cJSON *LP_inputjson(bits256 txid,int32_t vout,char *spendscriptstr)
{
cJSON *sobj,*item = cJSON_CreateObject();
jaddbits256(item,"txid",txid);
jaddnum(item,"vout",vout);
sobj = cJSON_CreateObject();
jaddstr(sobj,"hex",spendscriptstr);
jadd(item,"scriptPubKey",sobj);
return(item);
}
int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_t amount,struct vin_info *V,struct LP_address_utxo **utxos,int32_t numunspents,int32_t suppress_pubkeys,int32_t ignore_cltverr,bits256 privkey,cJSON *privkeys,cJSON *vins,uint8_t *script,int32_t scriptlen)
{
char wifstr[128],spendscriptstr[128]; int32_t i,n,ind,abovei,belowi,maxmode=0; struct vin_info *vp; struct LP_address_utxo *up; int64_t above,below,remains = amount,total = 0;
*totalp = 0;
init_hexbytes_noT(spendscriptstr,script,scriptlen);
bitcoin_priv2wif(coin->wiftaddr,wifstr,privkey,coin->wiftype);
for (i=n=0; i<numunspents; i++)
{
below = above = 0;
abovei = belowi = -1;
if ( LP_vin_select(&abovei,&above,&belowi,&below,utxos,numunspents,remains,maxmode) < 0 )
{
printf("error finding unspent i.%d of %d, %.8f vs %.8f\n",i,numunspents,dstr(remains),dstr(amount));
return(0);
}
if ( belowi < 0 || abovei >= 0 )
ind = abovei;
else ind = belowi;
if ( ind < 0 )
{
printf("error finding unspent i.%d of %d, %.8f vs %.8f, abovei.%d belowi.%d ind.%d\n",i,numunspents,dstr(remains),dstr(amount),abovei,belowi,ind);
return(0);
}
up = utxos[ind];
utxos[ind] = utxos[--numunspents];
utxos[numunspents] = 0;
total += up->U.value;
remains -= up->U.value;
if ( remains <= 0 )
break;
if ( numunspents == 0 )
{
printf("total %.8f not enough for amount %.8f\n",dstr(total),dstr(amount));
return(0);
}
vp = &V[n++];
vp->N = vp->M = 1;
vp->signers[0].privkey = privkey;
jaddistr(privkeys,wifstr);
bitcoin_pubkey33(ctx,vp->signers[0].pubkey,privkey);
vp->suppress_pubkeys = suppress_pubkeys;
vp->ignore_cltverr = ignore_cltverr;
jaddi(vins,LP_inputjson(up->U.txid,up->U.vout,spendscriptstr));
//printf("%s value %.8f -> remains %.8f\n",coinaddr,dstr(value),dstr(remains));
}
*totalp = total;
return(n);
}
char *LP_createrawtransaction(int32_t *numvinsp,struct iguana_info *coin,struct vin_info *V,int32_t max,bits256 privkey,cJSON *outputs,cJSON *vins,cJSON *privkeys)
{
static void *ctx;
cJSON *txobj,*item; uint8_t addrtype,rmd160[20],script[64],spendscript[64]; char *coinaddr,*rawtxbytes; bits256 txid; uint32_t timestamp,locktime; int64_t change=0,adjust=0,total,value,amount = 0; int32_t i,scriptlen,spendlen,suppress_pubkeys,ignore_cltverr,numvouts=0,numvins=0,numutxos=0; struct LP_address_utxo *utxos[256]; struct LP_address *ap;
if ( ctx == 0 )
ctx = bitcoin_ctx();
*numvinsp = 0;
if ( sizeof(utxos)/sizeof(*utxos) != max )
{
printf("LP_createrawtransaction: internal error %ld != max.%d\n",sizeof(utxos)/sizeof(*utxos),max);
return(0);
}
if ( coin == 0 || outputs == 0 || (numvouts= cJSON_GetArraySize(outputs)) <= 0 )
{
printf("LP_createrawtransaction: illegal coin.%p outputs.%p or arraysize.%d, error\n",coin,outputs,numvouts);
return(0);
}
for (i=0; i<numvouts; i++)
{
item = jitem(outputs,i);
if ( (coinaddr= jfieldname(item)) != 0 )
{
if ( LP_address_isvalid(coin->symbol,coinaddr) <= 0 )
{
printf("LP_createrawtransaction %s i.%d of %d is invalid\n",coinaddr,i,numvouts);
return(0);
}
if ( (value= j64bits(item,coinaddr)) <= 0 )
{
printf("cant get value %s i.%d of %d %s\n",coinaddr,i,numvouts,jprint(outputs,0));
return(0);
}
amount += value;
}
else
{
printf("cant get fieldname.%d of %d %s\n",i,numvouts,jprint(outputs,0));
return(0);
}
}
LP_listunspent_issue(coin->symbol,coin->smartaddr,1);
if ( (ap= LP_addressfind(coin,coin->smartaddr)) == 0 )
{
printf("LP_createrawtransaction: cant find address data\n");
return(0);
}
memset(utxos,0,sizeof(utxos));
if ( (numutxos= LP_address_utxo_ptrs(0,utxos,max,ap)) <= 0 )
{
printf("LP_createrawtransaction: address_utxo_ptrs %d, error\n",numutxos);
return(0);
}
ignore_cltverr = 0;
suppress_pubkeys = 1;
scriptlen = bitcoin_standardspend(script,0,G.LP_myrmd160);
numvins = LP_vins_select(ctx,coin,&total,amount,V,utxos,numutxos,suppress_pubkeys,ignore_cltverr,privkey,privkeys,vins,script,scriptlen);
change = (total - amount);
timestamp = (uint32_t)time(NULL);
if ( strcmp("KMD",coin->symbol) == 0 )
locktime = timestamp - 777;
else locktime = 0;
txobj = bitcoin_txcreate(coin->symbol,coin->isPoS,locktime,1,timestamp);
jdelete(txobj,"vin");
jadd(txobj,"vin",vins);
if ( change < 6000 )
{
adjust = change / numvouts;
change = 0;
}
for (i=0; i<numvouts; i++)
{
item = jitem(outputs,i);
if ( (coinaddr= jfieldname(item)) != 0 )
{
if ( (value= j64bits(item,coinaddr)) <= 0 )
{
printf("cant get value i.%d of %d %s\n",i,numvouts,jprint(outputs,0));
return(0);
}
bitcoin_addr2rmd160(coin->taddr,&addrtype,rmd160,coinaddr);
spendlen = bitcoin_standardspend(spendscript,0,rmd160);
txobj = bitcoin_txoutput(txobj,spendscript,spendlen,value + adjust);
}
else
{
printf("cant get fieldname.%d of %d %s\n",i,numvouts,jprint(outputs,0));
return(0);
}
}
if ( change != 0 )
txobj = bitcoin_txoutput(txobj,script,scriptlen,change);
if ( (rawtxbytes= bitcoin_json2hex(coin->isPoS,&txid,txobj,V)) != 0 )
{
} else printf("error making rawtx suppress.%d\n",suppress_pubkeys);
free_json(privkeys);
free_json(txobj);
return(rawtxbytes);
}
char *LP_withdraw(struct iguana_info *coin,cJSON *argjson)
{
static void *ctx;
int32_t iter,completed=0,numvins,numvouts,datalen,suppress_pubkeys; bits256 privkey; char changeaddr[64],vinaddr[64],str[65],*signedtx=0,*rawtx=0; struct vin_info V[256]; cJSON *retjson,*outputs,*vins,*privkeys; struct iguana_msgtx msgtx; bits256 signedtxid; uint64_t txfee,newtxfee=10000;
if ( (outputs= jarray(&numvouts,argjson,"outputs")) == 0 )
{
printf("no outputs in argjson (%s)\n",jprint(argjson,0));
return(clonestr("{\"error\":\"no outputs specified\"}"));
}
txfee = coin->txfee;
if ( ctx == 0 )
ctx = bitcoin_ctx();
if ( txfee > 0 && txfee < 10000 )
txfee = 10000;
retjson = cJSON_CreateObject();
suppress_pubkeys = 0;
memset(signedtxid.bytes,0,sizeof(signedtxid));
safecopy(changeaddr,coin->smartaddr,sizeof(changeaddr));
safecopy(vinaddr,coin->smartaddr,sizeof(vinaddr));
privkey = LP_privkey(vinaddr,coin->taddr);
for (iter=0; iter<2; iter++)
{
if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,iter == 0 ? txfee : newtxfee,str,coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,privkey,0,0,0,0,0,rawtx->utxotxid,rawtx->utxovout,rawtx->I.destaddr,pubkey33,1,0,&destamount,rawtx->I.amount,changeaddr,vinaddr,rawtx->I.suppress_pubkeys)) != 0 )
privkeys = cJSON_CreateArray();
vins = cJSON_CreateArray();
memset(V,0,sizeof(V));
if ( (rawtx= LP_createrawtransaction(&numvins,coin,V,(int32_t)(sizeof(V)/sizeof(*V)),privkey,outputs,vins,privkeys)) != 0 )
{
completed = 0;
memset(&msgtx,0,sizeof(msgtx));
memset(signedtxid.bytes,0,sizeof(signedtxid));
if ( (completed= iguana_signrawtransaction(ctx,coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->longestchain,&msgtx,&signedtx,&signedtxid,V,numvins,rawtx,vins,privkeys)) < 0 )
printf("couldnt sign withdraw %s\n",bits256_str(str,signedtxid));
else if ( completed == 0 )
{
printf("incomplete signing withdraw (%s)\n",jprint(vins,0));
if ( signedtx != 0 )
free(signedtx), signedtx = 0;
} else printf("LP_withdraw %s -> %s\n",jprint(argjson,0),bits256_str(str,signedtxid));
datalen = (int32_t)strlen(signedtx) / 2;
if ( strcmp(coin->symbol,"BTC") == 0 )
{
@ -743,11 +969,18 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch
printf("txfee %.8f -> newtxfee %.8f\n",dstr(txfee),dstr(newtxfee));
} else break;
} else break;
if ( strcmp(str,"myfee") == 0 )
break;
free(rawtx);
rawtx = 0;
}
retjson = cJSON_CreateObject();
if ( rawtx != 0 )
jaddstr(retjson,"rawtx",rawtx);
if ( signedtx != 0 )
jaddstr(retjson,"hex",signedtx);
jaddbits256(retjson,"txid",signedtxid);
jadd(retjson,"complete",completed!=0?jtrue():jfalse());
return(jprint(retjson,1));
}*/
}
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)
{

2
iguana/exchanges/install

@ -1,5 +1,5 @@
#!/bin/bash
cp setconfirms balance listunspent electrum snapshot_balance snapshot_loop secretaddresses dividends snapshot goals goal portfolio autoprice deletemessages getmessages debug register registerall buy sell bestfit orderbook client run_osx client_osx run coins disable enable myprice myprices getcoins getpeers getpeersIP getprices help inv setprice status ../dexscripts
cp setconfirms balance listunspent electrum snapshot_balance snapshot_loop secretaddresses dividends snapshot goals goal portfolio autoprice deletemessages getmessages debug buy sell bestfit orderbook client run_osx client_osx run coins disable enable myprice myprices getcoins getpeers getpeersIP getprices help inv setprice status ../dexscripts
cp coins.json ..
cd ../dexscripts
#cp ../exchanges/passphrase ../exchanges/userpass .

3
iguana/exchanges/register

@ -1,3 +0,0 @@
#!/bin/bash
source userpass
curl --url "http://5.9.253.195:7783" --data "{\"userpass\":\"9bb4846d24136fc7c33515e45bccbab5c8fb7b57b411aa20057b371da9358255\",\"agent\":\"stats\",\"method\":\"register\",\"client\":\"6d3332be4904feafd326609bd76b66528dc7b2e2d75a7bd110c6bf8d19c4cf58\",\"pushaddr\":\"5.9.253.195\",\"pushport\":\"10000\"}"

4
iguana/exchanges/registerall

@ -1,4 +0,0 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"registerall\",\"numnodes\":10}"

3
iguana/exchanges/withdraw

@ -0,0 +1,3 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"withdraw\",\"coin\":\"KMD\",\"outputs\":[\"iRUgW6fLfVsLJ87Ng4zJTqNedJSKYQ9ToAf\":0.001, \"RUgW6fLfVsLJ87Ng4zJTqNedJSKYQ9ToAf\":0.002]}"
Loading…
Cancel
Save