From 15802718baff6a1c29cdd6d26be4403ffc75c37b Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 26 Feb 2018 11:13:39 +0200 Subject: [PATCH] Timelock --- iguana/exchanges/LP_commands.c | 5 +++ iguana/exchanges/LP_instantdex.c | 29 +++++++++++++ iguana/exchanges/LP_ordermatch.c | 4 +- iguana/exchanges/LP_transaction.c | 69 ++++++++++++++++++++++++++----- iguana/exchanges/timelock | 3 ++ 5 files changed, 97 insertions(+), 13 deletions(-) create mode 100755 iguana/exchanges/timelock diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index b7be20389..585e68745 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -163,6 +163,7 @@ bot_pause(botid)\n\ calcaddress(passphrase)\n\ instantdex_deposit(weeks, amount, broadcast=1)\n\ instantdex_claim()\n\ +timelock(coin, duration, destaddr=(tradeaddr), amount)\n\ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ \"}")); //sell(base, rel, price, basevolume, timeout=10, duration=3600)\n\ @@ -511,6 +512,10 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ { return(LP_sendrawtransaction(coin,jstr(argjson,"signedtx"))); } + else if ( strcmp(method,"timelock") == 0 ) + { + return(LP_timelock(coin,juint(argjson,"duration"),jstr(argjson,"destaddr"),jdouble(argjson,"amount")*SATOSHIDEN)); + } else if ( strcmp(method,"getrawtransaction") == 0 ) { return(jprint(LP_gettx(coin,jbits256(argjson,"txid"),0),1)); diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index e3215ba5f..019e5e644 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -164,6 +164,35 @@ int32_t LP_deposit_addr(char *symbol,char *p2shaddr,uint8_t *script,uint8_t tadd return(n); } +char *LP_timelock(char *symbol,uint32_t duration,char *destaddr,uint64_t satoshis) +{ + struct iguana_info *coin; uint32_t expiration; char *retstr,p2shaddr[64],redeemscript[256]; cJSON *argjson,*array,*item; int32_t n=0; uint8_t addrtype,rmd160[20],p2sh160[20],script[40]; + if ( (coin= LP_coinfind(symbol)) != 0 ) + { + expiration = (uint32_t)time(NULL) + duration; + if ( destaddr == 0 ) + destaddr = coin->smartaddr; + bitcoin_addr2rmd160(symbol,coin->taddr,&addrtype,rmd160,destaddr); + n = bitcoin_timelockspend(script,0,rmd160,expiration); + init_hexbytes_noT(redeemscript,script,n); + calc_rmd160_sha256(p2sh160,script,n); + bitcoin_address(symbol,p2shaddr,coin->taddr,coin->p2shtype,p2sh160,20); + argjson = cJSON_CreateObject(); + array = cJSON_CreateArray(); + item = cJSON_CreateObject(); + jaddnum(item,p2shaddr,dstr(satoshis)); + jaddi(array,item); + jadd(argjson,"outputs",array); + jaddstr(argjson,"opreturn",redeemscript); + //printf("deposit.(%s)\n",jprint(argjson,0)); + if ( (retstr= LP_withdraw(coin,argjson)) != 0 ) + { + printf("timelock.(%s)\n",retstr); + return(retstr); + } else return(clonestr("{\"error\":\"null return from LP_withdraw\"}")); + } else return(clonestr("{\"error\":\"cant find coin\"}")); +} + char *LP_instantdex_deposit(struct iguana_info *coin,int32_t weeks,double amount,int32_t broadcast) { char p2shaddr[64],*retstr,*hexstr; uint8_t script[512]; int32_t weeki,scriptlen; cJSON *argjson,*retjson,*array,*item,*obj; uint32_t timestamp; bits256 txid,sendtxid; uint64_t amount64; diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 7794e3bca..715e027f1 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -500,10 +500,10 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double //char str[65]; printf("BOB pubsock.%d binds to %d (%s)\n",pubsock,pair,bits256_str(str,qp->desthash)); bits256 zero; memset(zero.bytes,0,sizeof(zero)); - for (i=0; i<10; i++) + for (i=0; i<3; i++) { LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,jprint(reqjson,0)); - sleep(3); + sleep(10); if ( swap->received != 0 ) { printf("swap %u-%u has started t%u\n",swap->I.req.requestid,swap->I.req.quoteid,swap->received); diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 5509e9b15..bdc3cf94b 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1199,10 +1199,10 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ return(n); } -char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_info *coin,struct vin_info *V,int32_t max,bits256 privkey,cJSON *outputs,cJSON *vins,cJSON *privkeys,int64_t txfee,bits256 utxotxid,int32_t utxovout,uint32_t locktime) +char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_info *coin,struct vin_info *V,int32_t max,bits256 privkey,cJSON *outputs,cJSON *vins,cJSON *privkeys,int64_t txfee,bits256 utxotxid,int32_t utxovout,uint32_t locktime,char *opretstr) { static void *ctx; - cJSON *txobj,*item; uint8_t addrtype,rmd160[20],script[64],spendscript[256]; char *coinaddr,*rawtxbytes; bits256 txid; uint32_t timestamp; int64_t change=0,adjust=0,total,value,amount = 0; int32_t i,dustcombine,scriptlen,spendlen,suppress_pubkeys,ignore_cltverr,numvouts=0,numvins=0,numutxos=0; struct LP_address_utxo *utxos[LP_MAXVINS*256]; struct LP_address *ap; + cJSON *txobj,*item; uint8_t addrtype,rmd160[20],script[8192],spendscript[256]; char *coinaddr,*rawtxbytes,*scriptstr; bits256 txid; uint32_t timestamp; int64_t change=0,adjust=0,total,value,amount = 0; int32_t i,len,dustcombine,scriptlen,spendlen,suppress_pubkeys,ignore_cltverr,numvouts=0,numvins=0,numutxos=0; struct LP_address_utxo *utxos[LP_MAXVINS*256]; struct LP_address *ap; if ( ctx == 0 ) ctx = bitcoin_ctx(); *numvinsp = 0; @@ -1297,15 +1297,32 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf free_json(txobj); return(0); } - bitcoin_addr2rmd160(coin->symbol,coin->taddr,&addrtype,rmd160,coinaddr); - if ( addrtype == coin->pubtype ) - spendlen = bitcoin_standardspend(spendscript,0,rmd160); - else spendlen = bitcoin_p2shspend(spendscript,0,rmd160); - if ( i == numvouts-1 && strcmp(coinaddr,coin->smartaddr) == 0 && change != 0 ) + if ( (scriptstr= jstr(item,"script")) != 0 ) { - printf("combine last vout %.8f with change %.8f\n",dstr(value+adjust),dstr(change)); - value += change; - change = 0; + spendlen = (int32_t)strlen(scriptstr) >> 1; + if ( spendlen < sizeof(script) ) + { + decode_hex(script,spendlen,scriptstr); + printf("i.%d using external script.(%s)\n",i,scriptstr); + } + else + { + printf("custom script.%d too long %d\n",i,spendlen); + return(0); + } + } + else + { + bitcoin_addr2rmd160(coin->symbol,coin->taddr,&addrtype,rmd160,coinaddr); + if ( addrtype == coin->pubtype ) + spendlen = bitcoin_standardspend(spendscript,0,rmd160); + else spendlen = bitcoin_p2shspend(spendscript,0,rmd160); + if ( i == numvouts-1 && strcmp(coinaddr,coin->smartaddr) == 0 && change != 0 ) + { + printf("combine last vout %.8f with change %.8f\n",dstr(value+adjust),dstr(change)); + value += change; + change = 0; + } } txobj = bitcoin_txoutput(txobj,spendscript,spendlen,value + adjust); } @@ -1323,6 +1340,36 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf } if ( change != 0 ) txobj = bitcoin_txoutput(txobj,script,scriptlen,change); + if ( opretstr != 0 ) + { + spendlen = (int32_t)strlen(opretstr) >> 1; + if ( spendlen < sizeof(script) ) + { + len = 0; + script[len++] = SCRIPT_OP_RETURN; + if ( spendlen < 76 ) + script[len++] = spendlen; + else if ( spendlen <= 0xff ) + { + script[len++] = 0x4c; + script[len++] = spendlen; + } + else if ( spendlen <= 0xffff ) + { + script[len++] = 0x4d; + script[len++] = (spendlen & 0xff); + script[len++] = ((spendlen >> 8) & 0xff); + } + decode_hex(&script[len],spendlen,opretstr); + txobj = bitcoin_txoutput(txobj,len + script,scriptlen,change); + printf("OP_RETURN.[%d, %d] script.(%s)\n",len,spendlen,opretstr); + } + else + { + printf("custom script.%d too long %d\n",i,spendlen); + return(0); + } + } if ( (rawtxbytes= bitcoin_json2hex(coin->symbol,coin->isPoS,&txid,txobj,V)) != 0 ) { } else printf("error making rawtx suppress.%d\n",suppress_pubkeys); @@ -1378,7 +1425,7 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) vins = cJSON_CreateArray(); memset(V,0,sizeof(*V) * maxV); numvins = 0; - if ( (rawtx= LP_createrawtransaction(&txobj,&numvins,coin,V,maxV,privkey,outputs,vins,privkeys,iter == 0 ? txfee : newtxfee,utxotxid,utxovout,locktime)) != 0 ) + if ( (rawtx= LP_createrawtransaction(&txobj,&numvins,coin,V,maxV,privkey,outputs,vins,privkeys,iter == 0 ? txfee : newtxfee,utxotxid,utxovout,locktime,jstr(argjson,"opreturn"))) != 0 ) { completed = 0; memset(&msgtx,0,sizeof(msgtx)); diff --git a/iguana/exchanges/timelock b/iguana/exchanges/timelock new file mode 100755 index 000000000..a3fc3b688 --- /dev/null +++ b/iguana/exchanges/timelock @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"timelock\",\"coin\":\"KMD\",\"duration\":1000,\"amount\":1}"