Browse Source

basilisk

release/v0.1
jl777 9 years ago
parent
commit
1d6520e1a3
  1. 421
      basilisk/basilisk.c
  2. 45
      basilisk/basilisk.h
  3. 487
      basilisk/basilisk_bitcoin.c
  4. 41
      basilisk/basilisk_ether.c
  5. 41
      basilisk/basilisk_iota.c
  6. 41
      basilisk/basilisk_lisk.c
  7. 41
      basilisk/basilisk_nxt.c
  8. 41
      basilisk/basilisk_waves.c
  9. 5
      crypto777/bitcoind_RPC.c
  10. 4
      crypto777/m_LP
  11. 9
      iguana/SuperNET.h
  12. 76
      iguana/SuperNET_category.c
  13. 135
      iguana/exchanges/bitcoin.c
  14. 2
      iguana/iguana.sources
  15. 12
      iguana/iguana777.c
  16. 24
      iguana/iguana777.h
  17. 2
      iguana/iguana_blocks.c
  18. 4
      iguana/iguana_bundles.c
  19. 276
      iguana/iguana_payments.c
  20. 2
      iguana/iguana_peers.c
  21. 4
      iguana/iguana_rpc.c
  22. 91
      iguana/iguana_sign.c
  23. 2
      iguana/iguana_spendvectors.c
  24. 8
      iguana/m_LP
  25. 1
      iguana/m_LTC
  26. 2
      iguana/m_unix
  27. 4
      iguana/main.c
  28. 20
      iguana/swaps/iguana_BTCswap.c
  29. 2
      iguana/tests/balances
  30. 2
      iguana/tests/rawtx
  31. 1
      iguana/tests/rawtxB
  32. 8
      includes/iguana_apideclares.h

421
basilisk/basilisk.c

@ -0,0 +1,421 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "../iguana/iguana777.h"
char *basilisk_finish(struct basilisk_item *ptr,cJSON **argjsonp,int32_t besti)
{
int32_t i; char *retstr = 0;
for (i=0; i<ptr->numresults; i++)
{
if ( besti >= 0 && i != besti )
{
if ( ptr->results[i] != 0 )
free(ptr->results[i]);
if ( ptr->resultargs[i] != 0 )
free_json(ptr->resultargs[i]);
}
else
{
retstr = ptr->results[i];
if ( argjsonp != 0 )
*argjsonp = ptr->resultargs[i];
}
ptr->results[i] = 0;
ptr->resultargs[i] = 0;
}
ptr->finished = (uint32_t)time(NULL);
return(retstr);
}
#include "basilisk_bitcoin.c"
#include "basilisk_nxt.c"
#include "basilisk_ether.c"
#include "basilisk_waves.c"
#include "basilisk_lisk.c"
cJSON *basilisk_json(struct supernet_info *myinfo,cJSON *hexjson,uint32_t basilisktag,int32_t timeout)
{
char *str,*buf; cJSON *retjson;
jaddnum(hexjson,"basilisktag",basilisktag);
str = jprint(hexjson,0);
buf = malloc(strlen(str)*2 + 1);
init_hexbytes_noT(buf,(uint8_t *)str,(int32_t)strlen(str));
free(str);
retjson = cJSON_CreateObject();
jaddstr(retjson,"hexmsg",buf);
free(buf);
jaddstr(retjson,"agent","SuperNET");
jaddstr(retjson,"method","DHT");
jaddnum(retjson,"request",1);
jaddnum(retjson,"plaintext",1);
jaddbits256(retjson,"categoryhash",myinfo->basilisk_category);
jaddnum(retjson,"timeout",timeout);
return(retjson);
}
int32_t basilisk_submit(struct supernet_info *myinfo,cJSON *reqjson,int32_t timeout,int32_t fanout,struct basilisk_item *ptr)
{
int32_t i,j,k,l,r2,r,n; struct iguana_peer *addr; struct iguana_info *coin; char *reqstr; cJSON *tmpjson;
tmpjson = basilisk_json(myinfo,reqjson,ptr->basilisktag,timeout);
reqstr = jprint(tmpjson,1);
if ( fanout <= 0 )
fanout = BASILISK_MINFANOUT;
else if ( fanout > BASILISK_MAXFANOUT )
fanout = BASILISK_MAXFANOUT;
r2 = rand();
for (l=n=0; l<IGUANA_MAXCOINS; l++)
{
i = (l + r2) % IGUANA_MAXCOINS;
if ( (coin= Coins[i]) != 0 )
{
r = rand();
for (k=0; k<IGUANA_MAXPEERS; k++)
{
j = (k + r) % IGUANA_MAXPEERS;
if ( (addr= &coin->peers.active[j]) != 0 && addr->supernet != 0 && addr->usock >= 0 )
{
ptr->submit = (uint32_t)time(NULL);
iguana_send_supernet(addr,reqstr,0);
if ( n++ > fanout )
break;
}
}
}
}
free(reqstr);
return(n);
}
struct basilisk_item *basilisk_issue(struct supernet_info *myinfo,cJSON *hexjson,int32_t timeoutmillis,int32_t fanout,int32_t minresults,uint32_t basilisktag)
{
double expiration; struct basilisk_item *ptr;
ptr = calloc(1,sizeof(*ptr));
if ( basilisktag == 0 )
basilisktag = rand();
ptr->basilisktag = basilisktag;
queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0);
if ( basilisk_submit(myinfo,hexjson,timeoutmillis,fanout,ptr) > 0 )
{
if ( timeoutmillis >= 0 )
{
expiration = OS_milliseconds() + ((timeoutmillis == 0) ? BASILISK_TIMEOUT : timeoutmillis);
while ( OS_milliseconds() < expiration && ptr->finished == 0 && ptr->numresults < minresults )
usleep(timeoutmillis/100 + 1);
}
}
return(ptr);
}
void basilisk_functions(struct iguana_info *coin)
{
switch ( coin->protocol )
{
case IGUANA_PROTOCOL_BITCOIN:
coin->basilisk_balances = basilisk_bitcoinbalances;
coin->basilisk_rawtx = basilisk_bitcoinrawtx;
coin->basilisk_value = basilisk_bitcoinvalue;
break;
/*case IGUANA_PROTOCOL_IOTA:
coin->basilisk_balances = basilisk_iotabalances;
coin->basilisk_rawtx = basilisk_iotarawtx;
break;
case IGUANA_PROTOCOL_NXT:
coin->basilisk_balances = basilisk_nxtbalances;
coin->basilisk_rawtx = basilisk_nxtrawtx;
break;
case IGUANA_PROTOCOL_ETHER:
coin->basilisk_balances = basilisk_etherbalances;
coin->basilisk_rawtx = basilisk_etherrawtx;
break;
case IGUANA_PROTOCOL_WAVES:
coin->basilisk_balances = basilisk_wavesbalances;
coin->basilisk_rawtx = basilisk_wavesrawtx;
break;
case IGUANA_PROTOCOL_LISK:
coin->basilisk_balances = basilisk_liskbalances;
coin->basilisk_rawtx = basilisk_liskrawtx;
break;*/
}
}
char *basilisk_issuerawtx(struct supernet_info *myinfo,char *remoteaddr,uint32_t basilisktag,char *symbol,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *spendscriptstr,char *changeaddr,int64_t txfee,int32_t minconf,cJSON *addresses,int32_t timeout)
{
struct iguana_info *coin; char *rawtx=0;
*vinsp = 0;
if ( (coin= iguana_coinfind(symbol)) != 0 )
{
if ( coin->basilisk_rawtx != 0 )
rawtx = (*coin->basilisk_rawtx)(myinfo,coin,remoteaddr,basilisktag,vinsp,locktime,satoshis,changeaddr,txfee,addresses,minconf,spendscriptstr,timeout);
}
return(rawtx);
}
int64_t basilisk_issuebalances(struct supernet_info *myinfo,char *remoteaddr,int32_t basilisktag,char *symbol,cJSON **argsp,int32_t lastheight,int32_t minconf,cJSON *addresses,int32_t timeout)
{
struct iguana_info *coin; int64_t balance = 0;
*argsp = 0;
if ( (coin= iguana_coinfind(symbol)) != 0 )
{
if ( coin->basilisk_balances != 0 )
balance = (*coin->basilisk_balances)(myinfo,coin,remoteaddr,basilisktag,argsp,lastheight,minconf,addresses,timeout);
}
return(balance);
}
int64_t basilisk_issuevalue(struct supernet_info *myinfo,char *remoteaddr,int32_t basilisktag,char *symbol,cJSON **argsp,bits256 txid,int16_t vout,char *coinaddr,int32_t timeout)
{
struct iguana_info *coin; int64_t value = 0;
*argsp = 0;
if ( (coin= iguana_coinfind(symbol)) != 0 )
{
if ( coin->basilisk_value != 0 )
value = (*coin->basilisk_value)(myinfo,coin,remoteaddr,basilisktag,txid,vout,coinaddr,timeout);
}
return(value);
}
#include "../includes/iguana_apidefs.h"
#include "../includes/iguana_apideclares.h"
INT_ARRAY_STRING(basilisk,balances,lastheight,addresses,activecoin)
{
/*uint64_t amount,total = 0; cJSON *item,*result,*array,*retjson,*hexjson; int32_t i,n,minconf=0; char *retstr,*balancestr,*coinaddr;
retjson = cJSON_CreateObject();
if ( activecoin != 0 && activecoin[0] != 0 && (coin= iguana_coinfind(activecoin)) != 0 )
{
xxx
jadd(retjson,"balances",array);
jaddnum(retjson,"total",dstr(total));
if ( lastheight != 0 )
jaddnum(retjson,"lastheight",lastheight);
if ( remoteaddr != 0 && remoteaddr[0] != 0 && strcmp(remoteaddr,"127.0.0.1") != 0 )
{
//printf("remote req.(%s)\n",jprint(retjson,0));
hexjson = cJSON_CreateObject();
jaddstr(hexjson,"rawtx",jprint(retjson,1));
jaddstr(hexjson,"agent","iguana");
jaddstr(hexjson,"method","rawtx_result");
jaddstr(hexjson,"activecoin",activecoin);
jaddnum(hexjson,"basilisktag",lastheight);
retjson = iguana_json(myinfo,hexjson);
} else jaddstr(retjson,"result","success");
return(jprint(retjson,1));
}
else if ( remoteaddr == 0 || remoteaddr[0] == 0 || strcmp(remoteaddr,"127.0.0.1") == 0 )
{
if ( (retstr= basilisk_request_andwait(myinfo,&myinfo->basiliskQ,0,json,lastheight,juint(json,"timeout"))) == 0 )
return(clonestr("{\"error\":\"timeout waiting for remote request\"}"));
else return(retstr);
} else return(clonestr("{\"error\":\"invalid remoterequest when not relaynode\"}"));
} else */return(clonestr("{\"error\":\"invalid request for inactive coin\"}"));
}
STRING_ARRAY_OBJ_STRING(basilisk,rawtx,changeaddr,addresses,vals,spendscriptstr)
{
cJSON *argjson=0,*retjson,*hexjson,*valsobj; char *rawtx=0,*symbol=0; int64_t txfee,satoshis; uint32_t locktime,minconf,basilisktag; int32_t timeout;
//printf("RAWTX changeaddr.%s (%s) remote.(%s)\n",changeaddr==0?"":changeaddr,jprint(json,0),remoteaddr);
retjson = cJSON_CreateObject();
if ( spendscriptstr != 0 && spendscriptstr[0] != 0 && (symbol= jstr(vals,"coin")) != 0 )
{
minconf = juint(vals,"minconf");
locktime = juint(vals,"locktime");
if ( jobj(json,"timeout") != 0 )
timeout = jint(json,"timeout");
else timeout = jint(vals,"timeout");
satoshis = j64bits(vals,"amount");
txfee = j64bits(vals,"txfee");
if ( (basilisktag= juint(vals,"basilisktag")) == 0 )
OS_randombytes((uint8_t *)&basilisktag,sizeof(basilisktag));
if ( (rawtx= basilisk_issuerawtx(myinfo,remoteaddr,basilisktag,symbol,&argjson,locktime,satoshis,spendscriptstr,changeaddr,txfee,minconf,addresses,timeout)) != 0 )
{
//printf("return rawtx.(%s) remote.%p symbol.%s\n",rawtx,remoteaddr,symbol);
if ( remoteaddr != 0 && remoteaddr[0] != 0 && (coin= iguana_coinfind(symbol)) != 0 )
{
hexjson = cJSON_CreateObject();
jaddstr(hexjson,"rawtx",rawtx);
jaddstr(hexjson,"agent","basilisk");
jaddstr(hexjson,"method","result");
if ( argjson != 0 )
jadd(hexjson,"args",argjson);
valsobj = cJSON_CreateObject();
jaddstr(valsobj,"coin",symbol);
jadd(hexjson,"vals",valsobj);
retjson = basilisk_json(myinfo,hexjson,basilisktag,timeout);
free_json(hexjson);
}
else
{
jaddstr(retjson,"result",rawtx);
if ( argjson != 0 )
jadd(retjson,"args",argjson);
}
free(rawtx);
} else jaddstr(retjson,"error","couldnt create rawtx");
}
return(jprint(retjson,1));
}
INT_ARRAY_STRING(basilisk,result,basilisktag,argjson,hexmsg)
{
struct basilisk_item *ptr = calloc(1,sizeof(*ptr) + strlen(hexmsg) + 1);
ptr->results[0] = clonestr(hexmsg);
ptr->basilisktag = basilisktag;
if ( argjson != 0 )
ptr->resultargs[0] = jduplicate(argjson);
ptr->numresults = 1;
queue_enqueue("resultsQ",&myinfo->basilisks.resultsQ,&ptr->DL,0);
return(clonestr("{\"result\":\"queued basilisk return\"}"));
}
#include "../includes/iguana_apiundefs.h"
char *basilisk_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void *ptr,int32_t len,char *remoteaddr)
{
char *method="",*agent="",*retstr = 0; int32_t i,j; cJSON *vins,*json,*valsobj; struct iguana_info *coin=0; struct iguana_peer *addr;
if ( (json= cJSON_Parse(ptr)) != 0 )
{
printf("basilisk.(%s)\n",jprint(json,0));
agent = jstr(json,"agent");
method = jstr(json,"method");
valsobj = jobj(json,"vals");
if ( strcmp(agent,"basilisk") == 0 )
{
if ( valsobj != 0 && jobj(valsobj,"coin") != 0 )
coin = iguana_coinfind(jstr(valsobj,"coin"));
else if ( jstr(json,"activecoin") != 0 )
coin = iguana_coinfind(jstr(json,"activecoin"));
if ( coin != 0 )
{
if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 )
{
if ( valsobj != 0 && strcmp(method,"rawtx") == 0 )
{
uint64_t amount = j64bits(valsobj,"amount");
uint64_t txfee = j64bits(valsobj,"txfee");
int32_t minconf = juint(valsobj,"minconf");
int32_t timeout = juint(valsobj,"timeout");
uint32_t locktime = juint(valsobj,"locktime");
retstr = basilisk_issuerawtx(myinfo,remoteaddr,0,coin->symbol,&vins,locktime,amount,jstr(json,"spendscriptstr"),jstr(json,"changeaddr"),txfee,minconf,jobj(json,"addresses"),timeout);
}
else if ( strcmp(method,"balances") == 0 )
{
retstr = basilisk_balances(myinfo,coin,json,remoteaddr,juint(json,"lastheight"),jobj(json,"addresses"),jstr(json,"activecoin"));
}
if ( retstr == 0 )
return(0);
printf("basilisk will return.(%s)\n",retstr);
for (j=0; j<IGUANA_MAXCOINS; j++)
{
if ( (coin= Coins[j]) == 0 )
continue;
for (i=0; i<IGUANA_MAXPEERS; i++)
{
if ( (addr= &coin->peers.active[i]) != 0 && addr->usock >= 0 )
{
if ( addr->supernet != 0 && strcmp(addr->ipaddr,remoteaddr) == 0 )
{
printf("send back basilisk_result addr->supernet.%u to (%s)\n",addr->supernet,addr->ipaddr);
iguana_send_supernet(addr,retstr,0);
free_json(json);
return(retstr);
}
}
if ( 0 && addr->ipbits != 0 )
printf("i.%d (%s) vs (%s) %s\n",i,addr->ipaddr,remoteaddr,coin->symbol);
}
}
}
else
{
if ( strcmp(method,"result") == 0 )
{
printf("got rawtx.(%s)\n",jstr(json,"hexmsg"));
return(basilisk_result(myinfo,coin,json,remoteaddr,juint(json,"basilisktag"),jobj(json,"args"),jstr(json,"hexmsg")));
}
}
}
}
}
if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 )
printf("unhandled bitcoin_hexmsg.(%d) from %s (%s/%s)\n",len,remoteaddr,agent,method);
free_json(json);
return(retstr);
}
void basilisks_loop(void *arg)
{
struct basilisk_item *ptr,*tmp,*pending; int32_t i,flag,n; struct supernet_info *myinfo = arg;
uint8_t *blockspace; struct OS_memspace RAWMEM; struct iguana_info *coin;
memset(&RAWMEM,0,sizeof(RAWMEM));
blockspace = calloc(1,IGUANA_MAXPACKETSIZE);
while ( 1 )
{
for (i=0; i<IGUANA_MAXCOINS; i++)
if ( (coin= Coins[i]) != 0 && coin->RELAYNODE == 0 && coin->VALIDATENODE == 0 && coin->active != 0 && coin->chain->userpass[0] != 0 )
basilisk_bitcoinscan(coin,blockspace,&RAWMEM);
if ( (ptr= queue_dequeue(&myinfo->basilisks.submitQ,0)) != 0 )
{
if ( ptr->finished == 0 )
HASH_ADD(hh,myinfo->basilisks.issued,basilisktag,sizeof(ptr->basilisktag),ptr);
else free(ptr);
continue;
}
else if ( (ptr= queue_dequeue(&myinfo->basilisks.resultsQ,0)) != 0 )
{
HASH_FIND(hh,myinfo->basilisks.issued,&ptr->basilisktag,sizeof(ptr->basilisktag),pending);
if ( pending != 0 )
{
if ( (n= pending->numresults) < sizeof(pending->results)/sizeof(*pending->results) )
{
pending->results[n] = ptr->results[0];
pending->resultargs[n] = ptr->resultargs[0];
pending->numresults++;
}
}
free(ptr);
continue;
}
else
{
flag = 0;
HASH_ITER(hh,myinfo->basilisks.issued,ptr,tmp)
{
if ( ptr->finished != 0 )
{
HASH_DELETE(hh,myinfo->basilisks.issued,ptr);
free(ptr);
flag++;
}
}
if ( flag == 0 )
usleep(100000);
}
}
}
void basilisks_init(struct supernet_info *myinfo)
{
bits256 basiliskhash;
iguana_initQ(&myinfo->basilisks.submitQ,"submitQ");
iguana_initQ(&myinfo->basilisks.resultsQ,"resultsQ");
basiliskhash = calc_categoryhashes(0,"basilisk",0);
myinfo->basilisk_category = basiliskhash;
category_subscribe(myinfo,basiliskhash,GENESIS_PUBKEY);
category_processfunc(basiliskhash,GENESIS_PUBKEY,basilisk_hexmsg);
category_processfunc(basiliskhash,myinfo->myaddr.persistent,basilisk_hexmsg);
myinfo->basilisks.launched = iguana_launch(iguana_coinfind("BTCD"),"basilisks_loop",basilisks_loop,myinfo,IGUANA_PERMTHREAD);
}

45
basilisk/basilisk.h

@ -0,0 +1,45 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#ifndef H_BASILISK_H
#define H_BASILISK_H
#include "../iguana/iguana777.h"
#define BASILISK_TIMEOUT 30000
#define BASILISK_MINFANOUT 8
#define BASILISK_MAXFANOUT 64
struct basilisk_value { bits256 txid; int64_t value; int16_t vout; char coinaddr[64]; };
struct basilisk_item
{
struct queueitem DL; UT_hash_handle hh;
uint32_t submit,finished,basilisktag,numresults,numexact;
char *results[BASILISK_MAXFANOUT]; cJSON *resultargs[BASILISK_MAXFANOUT];
};
struct basilisk_info
{
queue_t resultsQ,submitQ; void *launched; //portable_mutex_t *mutex;
struct basilisk_item *issued;
struct basilisk_value values[8192]; int32_t numvalues;
};
struct basilisk_item *basilisk_issue(struct supernet_info *myinfo,cJSON *hexjson,int32_t timeoutmillis,int32_t fanout,int32_t minresults,uint32_t basilisktag);
void basilisks_init(struct supernet_info *myinfo);
char *basilisk_issuerawtx(struct supernet_info *myinfo,char *remoteaddr,uint32_t basilisktag,char *symbol,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *spendscriptstr,char *changeaddr,int64_t txfee,int32_t minconf,cJSON *addresses,int32_t timeout);
#endif

487
basilisk/basilisk_bitcoin.c

@ -0,0 +1,487 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#ifdef bitcoincancalculatebalances
int64_t bitcoin_value(struct iguana_info *coin,bits256 txid,int16_t vout,char *coinaddr)
{
char params[512],str[65]; char *curlstr; cJSON *txobj,*vouts,*item,*sobj,*addrs; int32_t j,m,n; int64_t value = 0;
sprintf(params,"[\"%s\", 1]",bits256_str(str,txid));
if ( (curlstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getrawtransaction",params)) != 0 )
{
if ( (txobj= cJSON_Parse(curlstr)) != 0 )
{
if ( (vouts= jarray(&n,txobj,"vout")) != 0 && vout < n )
{
item = jitem(vouts,vout);
if ( (sobj= jobj(item,"scriptPubKey")) != 0 && (addrs= jarray(&m,sobj,"addresses")) != 0 )
{
for (j=0; j<m; j++)
{
if ( strcmp(jstri(addrs,j),coinaddr) == 0 )
{
value = SATOSHIDEN * jdouble(item,"amount");
break;
}
}
}
}
free_json(txobj);
}
free(curlstr);
}
return(value);
}
char *bitcoin_balance(struct iguana_info *coin,char *coinaddr,int32_t lastheight,int32_t minconf)
{
int32_t i,n,height,maxconf=1<<30; int64_t balance = 0; char params[512],*curlstr; cJSON *array,*retjson,*curljson;
retjson = cJSON_CreateObject();
if ( (curlstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getinfo",params)) != 0 )
{
if ( (curljson= cJSON_Parse(curlstr)) != 0 )
{
if ( (height= juint(curljson,"blocks")) > lastheight )
maxconf = height - lastheight;
free_json(curljson);
}
free(curlstr);
}
sprintf(params,"%d, %d, [\"%s\"]",minconf,maxconf,coinaddr);
if ( (curlstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"listunspent",params)) != 0 )
{
if ( (array= cJSON_Parse(curlstr)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
balance += SATOSHIDEN * jdouble(jitem(array,i),"amount");
}
free_json(array);
}
free(curlstr);
}
jaddnum(retjson,"balance",dstr(balance));
return(jprint(retjson,1));
}
#else
char *bitcoin_blockhashstr(char *coinstr,char *serverport,char *userpass,int32_t height)
{
char numstr[128],*blockhashstr=0;
sprintf(numstr,"%d",height);
blockhashstr = bitcoind_passthru(coinstr,serverport,userpass,"getblockhash",numstr);
if ( blockhashstr == 0 || blockhashstr[0] == 0 )
{
printf("couldnt get blockhash for %u\n",height);
if ( blockhashstr != 0 )
free(blockhashstr);
return(0);
}
return(blockhashstr);
}
cJSON *bitcoin_blockjson(int32_t *heightp,char *coinstr,char *serverport,char *userpass,char *blockhashstr,int32_t height)
{
cJSON *json = 0; int32_t flag = 0; char buf[1024],*blocktxt = 0;
if ( blockhashstr == 0 )
blockhashstr = bitcoin_blockhashstr(coinstr,serverport,userpass,height), flag = 1;
if ( blockhashstr != 0 )
{
sprintf(buf,"\"%s\"",blockhashstr);
blocktxt = bitcoind_passthru(coinstr,serverport,userpass,"getblock",buf);
//printf("get_blockjson.(%d %s) %s\n",height,blockhashstr,blocktxt);
if ( blocktxt != 0 && blocktxt[0] != 0 && (json= cJSON_Parse(blocktxt)) != 0 && heightp != 0 )
if ( (*heightp= juint(json,"height")) != height )
*heightp = -1;
if ( flag != 0 && blockhashstr != 0 )
free(blockhashstr);
if ( blocktxt != 0 )
free(blocktxt);
}
return(json);
}
int32_t basilisk_bitcoinscan(struct iguana_info *coin,uint8_t origblockspace[IGUANA_MAXPACKETSIZE],struct OS_memspace *rawmem)
{
struct iguana_txblock txdata; int32_t len,starti,h,num=0,loadheight,hexlen,datalen,n,i,numtxids,flag=0,height=-1; cJSON *curljson,*blockjson,*txids; char *bitstr,*curlstr,params[128],str[65]; struct iguana_msghdr H; struct iguana_msgblock *msg; uint8_t *blockspace,revbits[4],bitsbuf[4];
strcpy(params,"[]");
if ( (curlstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getinfo",params)) != 0 )
{
if ( (curljson= cJSON_Parse(curlstr)) != 0 )
{
height = juint(curljson,"blocks");
free_json(curljson);
}
free(curlstr);
}
loadheight = coin->blocks.hwmchain.height;
if ( loadheight == 0 )
loadheight = 1;
while ( loadheight <= height )//&& coin->blocks.pending < 10 )
{
flag = 0;
if ( (blockjson= bitcoin_blockjson(&h,coin->symbol,coin->chain->serverport,coin->chain->userpass,0,loadheight)) != 0 )
{
blockspace = origblockspace;
msg = (void *)blockspace;
memset(msg,0,sizeof(*msg));
msg->H.version = juint(blockjson,"version");
msg->H.prev_block = jbits256(blockjson,"previousblockhash");
msg->H.merkle_root = jbits256(blockjson,"merkleroot");
msg->H.timestamp = juint(blockjson,"timestamp");
if ( (bitstr= jstr(blockjson,"bits")) != 0 )
{
decode_hex(revbits,sizeof(revbits),bitstr);
for (i=0; i<4; i++)
bitsbuf[i] = revbits[3 - i];
memcpy(&msg->H.bits,bitsbuf,sizeof(msg->H.bits));
}
msg->H.nonce = juint(blockjson,"nonce");
datalen = 80;
if ( (txids= jarray(&numtxids,blockjson,"tx")) != 0 )
{
msg->txn_count = numtxids;
if ( numtxids < 0xfd )
blockspace[datalen++] = numtxids;
else
{
blockspace[datalen++] = 0xfd;
blockspace[datalen++] = numtxids & 0xff;
blockspace[datalen++] = numtxids >> 8;
}
starti = datalen;
for (i=0; i<numtxids; i++)
{
sprintf(params,"[\"%s\"]",bits256_str(str,jbits256(jitem(txids,i),0)));
if ( (curlstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getrawtransaction",params)) != 0 )
{
//printf("%s txid.%d\n",curlstr,i);
if ( (hexlen= is_hexstr(curlstr,0)) > 1 )
{
hexlen >>= 1;
decode_hex(&blockspace[datalen],hexlen,curlstr);
datalen += hexlen;
}
free(curlstr);
}
}
num++;
coin->blocks.pending++;
if ( rawmem->ptr == 0 )
iguana_meminit(rawmem,"basilisk",0,IGUANA_MAXPACKETSIZE*3,0);
else iguana_memreset(rawmem);
memset(&txdata,0,sizeof(txdata));
memset(&H,0,sizeof(H));
if ( (n= iguana_gentxarray(coin,rawmem,&txdata,&len,blockspace,datalen)) == datalen )
{
len = n;
iguana_gotblockM(coin,0,&txdata,rawmem->ptr,&H,blockspace,datalen);
flag = 1;
//if ( (rand() % 1000) == 0 )
printf("%s height.%-7d datalen.%-6d | HWM.%d\n",coin->symbol,h,datalen,coin->blocks.hwmchain.height);
}
else
{
printf(" parse error block.%d txn_count.%d, n.%d len.%d vs datalen.%d\n",loadheight,txdata.block.RO.txn_count,n,len,datalen);
}
}
free_json(blockjson);
}
if ( flag == 0 )
break;
loadheight++;
}
if ( coin->blocks.pending > 0 )
coin->blocks.pending--;
return(num);
}
#endif
int32_t basilisk_bitcoinavail(struct iguana_info *coin)
{
if ( coin->VALIDATENODE != 0 || coin->RELAYNODE != 0 )
return(1);
//else if ( coin->chain->serverport[0] != 0 )
// return(1);
else return(0);
}
int64_t basilisk_bitcoinbalances(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **arrayp,int32_t lastheight,int32_t minconf,cJSON *addresses,int32_t timeoutmillis)
{
cJSON *array=0,*result,*item,*retjson,*hexjson; int32_t i,n,besti=-1; char *coinaddr,*balancestr=0,*retstr=0; int64_t total=0,amount,most=0; struct basilisk_item *ptr;
array = cJSON_CreateArray();
if ( coin != 0 && basilisk_bitcoinavail(coin) != 0 )
{
if ( (n= cJSON_GetArraySize(addresses)) > 0 )
{
for (i=0; i<n; i++)
{
coinaddr = jstri(addresses,i);
if ( coin->VALIDATENODE != 0 || coin->RELAYNODE != 0 )
balancestr = iguana_balance(myinfo,coin,0,remoteaddr,coin->symbol,coinaddr,lastheight,minconf);
//else balancestr = bitcoin_balance(coin,coinaddr,lastheight,minconf);
if ( balancestr != 0 )
{
if ( (result= cJSON_Parse(balancestr)) != 0 )
{
if ( jobj(result,"balance") != 0 )
{
item = cJSON_CreateObject();
amount = SATOSHIDEN * jdouble(result,"balance");
total += amount;
jaddnum(item,coinaddr,dstr(amount));
jaddi(array,item);
}
free_json(result);
}
free(balancestr);
}
}
}
}
else
{
hexjson = cJSON_CreateObject();
jaddnum(hexjson,"basilisktag",basilisktag);
jadd(hexjson,"addresses",jduplicate(addresses));
jaddnum(hexjson,"minconf",minconf);
jaddnum(hexjson,"lastheight",lastheight);
jaddstr(hexjson,"agent","basilisk");
jaddstr(hexjson,"method","balances");
if ( (ptr= basilisk_issue(myinfo,hexjson,timeoutmillis,0,1,basilisktag)) != 0 )
{
for (i=0; i<ptr->numresults; i++)
{
if ( ptr->results[i] == 0 )
continue;
if ( retstr != 0 && strcmp(ptr->results[i],retstr) == 0 )
ptr->numexact++;
if ( (retjson= cJSON_Parse(ptr->results[i])) != 0 )
{
if ( (total= j64bits(retjson,"balance")) > most )
{
most = total;
besti = i;
}
free_json(retjson);
}
}
retstr = basilisk_finish(ptr,arrayp,besti);
}
free_json(hexjson);
}
*arrayp = array;
return(most);
}
int64_t basilisk_bitcoinvalue(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,bits256 txid,int32_t vout,char *coinaddr,int32_t timeoutmillis)
{
int32_t i,height; struct basilisk_value *v; cJSON *hexjson; uint64_t value = 0; struct basilisk_item *ptr;
if ( coin != 0 && basilisk_bitcoinavail(coin) != 0 )
{
if ( coin->VALIDATENODE != 0 || coin->RELAYNODE != 0 )
{
if ( iguana_unspentindfind(coin,coinaddr,0,0,&value,&height,txid,vout,coin->bundlescount) > 0 )
return(value);
} //else return(bitcoin_value(coin,txid,vout,coinaddr));
}
else
{
if ( (v= myinfo->basilisks.values) != 0 )
{
for (i=0; i<myinfo->basilisks.numvalues; i++,v++)
{
if ( v->vout == vout && bits256_cmp(txid,v->txid) == 0 && strcmp(v->coinaddr,coinaddr) == 0 )
return(v->value);
}
}
hexjson = cJSON_CreateObject();
jaddnum(hexjson,"basilisktag",basilisktag);
jaddstr(hexjson,"address",coinaddr);
jaddbits256(hexjson,"txid",txid);
jaddnum(hexjson,"vout",vout);
jaddstr(hexjson,"agent","basilisk");
jaddstr(hexjson,"method","value");
if ( (ptr= basilisk_issue(myinfo,hexjson,timeoutmillis,0,1,basilisktag)) != 0 )
{
v = &myinfo->basilisks.values[myinfo->basilisks.numvalues++];
strcpy(v->coinaddr,coinaddr);
v->value = value;
v->txid = txid;
}
free_json(hexjson);
}
return(value);
}
int64_t basilisk_bitcointxcost(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t locktime,int64_t satoshis,int64_t txfee,cJSON *addresses,char *spendscriptstr,char *changeaddr,char *rawtx,cJSON *vins)
{
cJSON *txobj,*vouts,*vin,*sobj,*addrs; int64_t change=0,outputsum=0,inputsum=0,spentsatoshis=0,cost = -1; int32_t i,j,m,numaddrs,spendlen,n; struct iguana_msgtx msgtx; uint8_t extraspace[8192],script[IGUANA_MAXSCRIPTSIZE],asmtype; struct vin_info V; char *scriptstr,str[65]; bits256 txid;
if ( coin != 0 )
{
spendlen = (int32_t)strlen(spendscriptstr) >> 1;
decode_hex(script,spendlen,spendscriptstr);
if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,rawtx,extraspace,sizeof(extraspace))) != 0 )
{
if ( juint(txobj,"locktime") != locktime )
{
printf("locktime mismatch %u != %u\n",juint(txobj,"locktime"),locktime);
return(-1);
}
else if ( jobj(txobj,"error") == 0 && (vins= jarray(&n,txobj,"vin")) != 0 && cJSON_GetArraySize(vins) == msgtx.tx_in )
{
numaddrs = cJSON_GetArraySize(addresses);
for (i=0; i<msgtx.tx_in; i++)
{
vin = jitem(vins,i);
if ( (sobj= jobj(vin,"scriptPubKey")) != 0 && (scriptstr= jstr(sobj,"hex")) != 0 )
{
memset(&V,0,sizeof(V));
V.spendlen = (int32_t)strlen(scriptstr) >> 1;
decode_hex(V.spendscript,V.spendlen,scriptstr);
asmtype = _iguana_calcrmd160(coin,&V);
if ( basilisk_bitcoinvalue(myinfo,coin,remoteaddr,0,msgtx.vins[i].prev_hash,msgtx.vins[i].prev_vout,V.coinaddr,10000) == V.amount )
{
inputsum += V.amount;
for (j=0; j<numaddrs; j++)
if ( strcmp(jstri(addresses,j),V.coinaddr) == 0 )
break;
if ( j == numaddrs )
{
printf("spend of invalid input address.(%s)\n",V.coinaddr);
free_json(txobj);
return(-1);
}
}
else
{
printf("spend of invalid %s unspent.(%s).%d\n",V.coinaddr,bits256_str(str,msgtx.vins[i].prev_hash),msgtx.vins[i].prev_vout);
free_json(txobj);
return(-1);
}
}
}
if ( (vouts= jarray(&n,txobj,"vout")) != 0 && n == msgtx.tx_out )
{
for (i=0; i<msgtx.tx_out; i++)
{
outputsum += msgtx.vouts[i].value;
if ( spendlen == msgtx.vouts[i].pk_scriptlen && memcmp(script,msgtx.vouts[i].pk_script,spendlen) == 0 )
{
spentsatoshis = msgtx.vouts[i].value;
continue;
}
else
{
if ( (sobj= jobj(jitem(vouts,i),"scriptPubKey")) != 0 && (addrs= jarray(&m,sobj,"addresses")) != 0 )
{
if ( m == 1 && strcmp(jstri(addrs,0),changeaddr) == 0 )
{
change = msgtx.vouts[i].value;
printf("verify it is normal spend for %s\n",changeaddr);
continue;
}
}
}
cost += msgtx.vouts[i].value;
}
}
}
free_json(txobj);
}
}
if ( spentsatoshis != satoshis )
{
printf("spentsatoshis %.8f != expected %.8f, change %.8f\n",dstr(spentsatoshis),dstr(satoshis),dstr(change));
return(-1);
}
if ( (inputsum - outputsum) != txfee )
{
printf("inputsum %.8f - outputsum %.8f = %.8f != txfee %.8f\n",dstr(inputsum),dstr(outputsum),dstr(inputsum)-dstr(outputsum),dstr(txfee));
return(-1);
}
return(cost);
}
char *basilisk_bitcoinrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *changeaddr,uint64_t txfee,cJSON *addresses,int32_t minconf,char *spendscriptstr,int32_t timeoutmillis)
{
uint8_t buf[IGUANA_MAXSCRIPTSIZE]; int32_t i,spendlen,besti=-1; cJSON *hexjson,*valsobj,*txobj = 0; char *retstr=0,*rawtx = 0; int64_t cost,bestcost=-1; struct basilisk_item *ptr;
*vinsp = 0;
if ( coin != 0 && basilisk_bitcoinavail(coin) != 0 )
{
if ( coin->VALIDATENODE != 0 || coin->RELAYNODE != 0 )
{
if ( txfee == 0 )
txfee = coin->chain->txfee;
if ( (txobj= bitcoin_txcreate(coin,locktime)) != 0 )
{
spendlen = (int32_t)strlen(spendscriptstr) >> 1;
decode_hex(buf,spendlen,spendscriptstr);
bitcoin_txoutput(coin,txobj,buf,spendlen,satoshis);
rawtx = iguana_calcrawtx(myinfo,coin,vinsp,txobj,satoshis,changeaddr,txfee,addresses,minconf);
} else printf("error creating txobj\n");
} //else rawtx = bitcoin_calcrawtx(myinfo,coin,vinsp,satoshis,spendscriptstr,changeaddr,txfee,addresses,minconf,locktime);
if ( rawtx != 0 )
{
if ( *vinsp != 0 )
{
free_json(txobj);
//printf("return locally generated rawtx.(%s) vins.%p\n",rawtx,*vinsp);
return(rawtx);
} else free(rawtx);
}
}
if ( txobj != 0 )
free_json(txobj);
if ( addresses != 0 )
{
valsobj = cJSON_CreateObject();
jaddnum(valsobj,"basilisktag",basilisktag);
jaddstr(valsobj,"coin",coin->symbol);
jadd64bits(valsobj,"amount",satoshis);
jadd64bits(valsobj,"txfee",txfee);
jaddnum(valsobj,"minconf",minconf);
jaddnum(valsobj,"locktime",locktime);
hexjson = cJSON_CreateObject();
jaddstr(hexjson,"changeaddr",changeaddr);
jaddstr(hexjson,"spendscriptstr",spendscriptstr);
jadd(hexjson,"addresses",jduplicate(addresses));
jadd(hexjson,"vals",valsobj);
jaddstr(hexjson,"agent","basilisk");
jaddstr(hexjson,"method","rawtx");
if ( (ptr= basilisk_issue(myinfo,hexjson,timeoutmillis,0,1,basilisktag)) != 0 )
{
for (i=0; i<ptr->numresults; i++)
{
if ( ptr->results[i] == 0 )
continue;
if ( retstr != 0 && strcmp(ptr->results[i],retstr) == 0 )
ptr->numexact++;
if ( (cost= basilisk_bitcointxcost(myinfo,coin,remoteaddr,locktime,satoshis,txfee,addresses,spendscriptstr,changeaddr,ptr->results[i],ptr->resultargs[i])) >= 0 && (bestcost == 0 || cost < bestcost) )
{
if ( retstr != 0 )
ptr->numexact = 0;
retstr = ptr->results[i];
bestcost = cost;
besti = i;
}
}
retstr = basilisk_finish(ptr,vinsp,besti);
}
free_json(hexjson);
}
return(retstr);
}

41
basilisk/basilisk_ether.c

@ -0,0 +1,41 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
char *basilisk_etherrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *changeaddr,uint64_t txfee,cJSON *addresses,int32_t minconf,char *spendscriptstr,int32_t timeoutmillis)
{
cJSON *hexjson,*valsobj; char *retstr = 0; struct basilisk_item *ptr;
*vinsp = 0;
if ( addresses != 0 )
{
valsobj = cJSON_CreateObject();
jaddnum(valsobj,"basilisktag",basilisktag);
jaddstr(valsobj,"coin",coin->symbol);
jadd64bits(valsobj,"amount",satoshis);
jadd64bits(valsobj,"txfee",txfee);
jaddnum(valsobj,"minconf",minconf);
jaddnum(valsobj,"locktime",locktime);
hexjson = cJSON_CreateObject();
jaddstr(hexjson,"changeaddr",changeaddr);
jaddstr(hexjson,"spendscriptstr",spendscriptstr);
jadd(hexjson,"addresses",jduplicate(addresses));
jadd(hexjson,"vals",valsobj);
jaddstr(hexjson,"agent","basilisk");
jaddstr(hexjson,"method","rawtx");
if ( (ptr= basilisk_issue(myinfo,hexjson,timeoutmillis,0,1,basilisktag)) != 0 )
retstr = basilisk_finish(ptr,vinsp,0);
free_json(hexjson);
}
return(retstr);
}

41
basilisk/basilisk_iota.c

@ -0,0 +1,41 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
char *basilisk_iotarawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *changeaddr,uint64_t txfee,cJSON *addresses,int32_t minconf,char *spendscriptstr,int32_t timeoutmillis)
{
cJSON *hexjson,*valsobj; char *retstr = 0; struct basilisk_item *ptr;
*argsjsonp = 0;
if ( addresses != 0 )
{
valsobj = cJSON_CreateObject();
jaddnum(valsobj,"basilisktag",basilisktag);
jaddstr(valsobj,"coin",symbol);
jadd64bits(valsobj,"amount",satoshis);
jadd64bits(valsobj,"txfee",txfee);
jaddnum(valsobj,"minconf",minconf);
jaddnum(valsobj,"locktime",locktime);
hexjson = cJSON_CreateObject();
jaddstr(hexjson,"changeaddr",changeaddr);
jaddstr(hexjson,"spendscriptstr",spendscriptstr);
jadd(hexjson,"addresses",jduplicate(addresses));
jadd(hexjson,"vals",valsobj);
jaddstr(hexjson,"agent","basilisk");
jaddstr(hexjson,"method","rawtx");
if ( (ptr= basilisk_issue(myinfo,hexjson,timeoutmillis,0,1,basilisktag)) != 0 )
retstr = basilisk_finish(ptr,argsjsonp,0);
free_json(hexjson);
}
return(retstr);
}

41
basilisk/basilisk_lisk.c

@ -0,0 +1,41 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
char *basilisk_liskrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *changeaddr,uint64_t txfee,cJSON *addresses,int32_t minconf,char *spendscriptstr,int32_t timeoutmillis)
{
cJSON *hexjson,*valsobj; char *retstr = 0; struct basilisk_item *ptr;
*vinsp = 0;
if ( addresses != 0 )
{
valsobj = cJSON_CreateObject();
jaddnum(valsobj,"basilisktag",basilisktag);
jaddstr(valsobj,"coin",coin->symbol);
jadd64bits(valsobj,"amount",satoshis);
jadd64bits(valsobj,"txfee",txfee);
jaddnum(valsobj,"minconf",minconf);
jaddnum(valsobj,"locktime",locktime);
hexjson = cJSON_CreateObject();
jaddstr(hexjson,"changeaddr",changeaddr);
jaddstr(hexjson,"spendscriptstr",spendscriptstr);
jadd(hexjson,"addresses",jduplicate(addresses));
jadd(hexjson,"vals",valsobj);
jaddstr(hexjson,"agent","basilisk");
jaddstr(hexjson,"method","rawtx");
if ( (ptr= basilisk_issue(myinfo,hexjson,timeoutmillis,0,1,basilisktag)) != 0 )
retstr = basilisk_finish(ptr,vinsp,0);
free_json(hexjson);
}
return(retstr);
}

41
basilisk/basilisk_nxt.c

@ -0,0 +1,41 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
char *basilisk_nxtrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *changeaddr,uint64_t txfee,cJSON *addresses,int32_t minconf,char *spendscriptstr,int32_t timeoutmillis)
{
cJSON *hexjson,*valsobj; char *retstr = 0; struct basilisk_item *ptr;
*vinsp = 0;
if ( addresses != 0 )
{
valsobj = cJSON_CreateObject();
jaddnum(valsobj,"basilisktag",basilisktag);
jaddstr(valsobj,"coin",coin->symbol);
jadd64bits(valsobj,"amount",satoshis);
jadd64bits(valsobj,"txfee",txfee);
jaddnum(valsobj,"minconf",minconf);
jaddnum(valsobj,"locktime",locktime);
hexjson = cJSON_CreateObject();
jaddstr(hexjson,"changeaddr",changeaddr);
jaddstr(hexjson,"spendscriptstr",spendscriptstr);
jadd(hexjson,"addresses",jduplicate(addresses));
jadd(hexjson,"vals",valsobj);
jaddstr(hexjson,"agent","basilisk");
jaddstr(hexjson,"method","rawtx");
if ( (ptr= basilisk_issue(myinfo,hexjson,timeoutmillis,0,1,basilisktag)) != 0 )
retstr = basilisk_finish(ptr,vinsp,0);
free_json(hexjson);
}
return(retstr);
}

41
basilisk/basilisk_waves.c

@ -0,0 +1,41 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
char *basilisk_wavesrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *changeaddr,uint64_t txfee,cJSON *addresses,int32_t minconf,char *spendscriptstr,int32_t timeoutmillis)
{
cJSON *hexjson,*valsobj; char *retstr = 0; struct basilisk_item *ptr;
*vinsp = 0;
if ( addresses != 0 )
{
valsobj = cJSON_CreateObject();
jaddnum(valsobj,"basilisktag",basilisktag);
jaddstr(valsobj,"coin",coin->symbol);
jadd64bits(valsobj,"amount",satoshis);
jadd64bits(valsobj,"txfee",txfee);
jaddnum(valsobj,"minconf",minconf);
jaddnum(valsobj,"locktime",locktime);
hexjson = cJSON_CreateObject();
jaddstr(hexjson,"changeaddr",changeaddr);
jaddstr(hexjson,"spendscriptstr",spendscriptstr);
jadd(hexjson,"addresses",jduplicate(addresses));
jadd(hexjson,"vals",valsobj);
jaddstr(hexjson,"agent","basilisk");
jaddstr(hexjson,"method","rawtx");
if ( (ptr= basilisk_issue(myinfo,hexjson,timeoutmillis,0,1,basilisktag)) != 0 )
retstr = basilisk_finish(ptr,vinsp,0);
free_json(hexjson);
}
return(retstr);
}

5
crypto777/bitcoind_RPC.c

@ -15,8 +15,7 @@
#include "OS_portable.h" #include "OS_portable.h"
//#define USE_CURL #ifdef LIQUIDITY_PROVIDER
#ifdef USE_CURL
#ifdef _WIN32 #ifdef _WIN32
#include <curl.h> #include <curl.h>
#include <easy.h> #include <easy.h>
@ -199,7 +198,7 @@ try_again:
free(s.ptr); free(s.ptr);
return(0); return(0);
} }
else if ( numretries >= 2 ) else if ( numretries >= 5 )
{ {
printf("Maximum number of retries exceeded!\n"); printf("Maximum number of retries exceeded!\n");
free(s.ptr); free(s.ptr);

4
crypto777/m_LP

@ -0,0 +1,4 @@
git pull
rm *.o
gcc -c -DLIQUIDITY_PROVIDER -O2 *.c jpeg/*.c jpeg/unix/*.c -I/usr/lib/x86_64-linux-gnu/curl
rm -f ../agents/libcrypto777.a; ar rcu ../agents/libcrypto777.a *.o

9
iguana/SuperNET.h

@ -73,21 +73,23 @@ struct supernet_address
char NXTADDR[32],BTC[64],BTCD[64]; char NXTADDR[32],BTC[64],BTCD[64];
}; };
struct rawtx_queue { struct queueitem DL; cJSON *vins; uint32_t rawtxtag; char rawtx[]; }; struct supernet_info;
#include "../basilisk/basilisk.h"
struct supernet_info struct supernet_info
{ {
char ipaddr[64],transport[8]; int32_t APISLEEP; int32_t iamrelay; uint32_t expiration,dirty; char ipaddr[64],transport[8]; int32_t APISLEEP; int32_t iamrelay; uint32_t expiration,dirty;
int32_t Debuglevel,readyflag,dead,POLLTIMEOUT; char rpcsymbol[16],LBpoint[64],PUBpoint[64]; int32_t Debuglevel,readyflag,dead,POLLTIMEOUT; char rpcsymbol[16],LBpoint[64],PUBpoint[64];
//int32_t pullsock,subclient,lbclient,lbserver,servicesock,pubglobal,pubrelays,numservers; //int32_t pullsock,subclient,lbclient,lbserver,servicesock,pubglobal,pubrelays,numservers;
bits256 privkey,persistent_priv,BTCmarkerhash,instantdex_category,pangea_category,bitcoin_category; bits256 privkey,persistent_priv,BTCmarkerhash,instantdex_category,pangea_category,basilisk_category;
char secret[2048],NXTAPIURL[512],permanentfile[1024]; char secret[2048],NXTAPIURL[512],permanentfile[1024];
uint8_t *recvbuf[6]; uint8_t *recvbuf[6];
struct supernet_address myaddr; struct supernet_address myaddr;
int32_t LBsock,PUBsock,reqsock,subsock,networktimeout,maxdelay; int32_t LBsock,PUBsock,reqsock,subsock,networktimeout,maxdelay;
uint16_t LBport,PUBport,reqport,subport,rpcport,publicRPC,argport; uint16_t LBport,PUBport,reqport,subport,rpcport,publicRPC,argport;
//struct nn_pollfd pfd[SUPERNET_MAXAGENTS]; //struct relay_info active; //struct nn_pollfd pfd[SUPERNET_MAXAGENTS]; //struct relay_info active;
struct supernet_agent agents[SUPERNET_MAXAGENTS]; queue_t acceptQ,rawtxQ; struct supernet_agent agents[SUPERNET_MAXAGENTS]; queue_t acceptQ;
struct basilisk_info basilisks;
int32_t numagents,numexchanges; int32_t numagents,numexchanges;
struct exchange_info *tradingexchanges[SUPERNET_MAXEXCHANGES]; struct exchange_info *tradingexchanges[SUPERNET_MAXEXCHANGES];
struct iguana_waccount *wallet; void *ctx; struct iguana_waccount *wallet; void *ctx;
@ -194,6 +196,7 @@ int32_t SuperNET_MYINFOS(struct supernet_info **myinfos,int32_t max);
FILE *myfopen(char *fname,char *mode); FILE *myfopen(char *fname,char *mode);
int32_t myfclose(FILE *fp); int32_t myfclose(FILE *fp);
cJSON *SuperNET_rosettajson(bits256 privkey,int32_t showprivs); cJSON *SuperNET_rosettajson(bits256 privkey,int32_t showprivs);
char *basilisk_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void *ptr,int32_t len,char *remoteaddr);
#endif #endif

76
iguana/SuperNET_category.c

@ -202,77 +202,9 @@ char *SuperNET_categorymulticast(struct supernet_info *myinfo,int32_t surveyflag
return(retstr); return(retstr);
} }
char *bitcoin_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void *ptr,int32_t len,char *remoteaddr)
{
char *method="",*agent="",*retstr = 0; int32_t i,j; cJSON *json,*valsobj; struct iguana_info *coin=0; struct iguana_peer *addr;
if ( (json= cJSON_Parse(ptr)) != 0 )
{
printf("bitcoinprocess.(%s)\n",jprint(json,0));
agent = jstr(json,"agent");
method = jstr(json,"method");
valsobj = jobj(json,"vals");
if ( strcmp(agent,"iguana") == 0 )
{
if ( valsobj != 0 && jobj(valsobj,"coin") != 0 )
coin = iguana_coinfind(jstr(valsobj,"coin"));
else if ( jstr(json,"activecoin") != 0 )
coin = iguana_coinfind(jstr(json,"activecoin"));
if ( coin != 0 )
{
if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 )
{
if ( valsobj != 0 && strcmp(method,"rawtx") == 0 )
{
retstr = iguana_rawtx(myinfo,coin,json,remoteaddr,jstr(json,"changeaddr"),jobj(json,"addresses"),valsobj,jstr(json,"spendscriptstr"));
}
else if ( strcmp(method,"balances") == 0 )
{
retstr = iguana_balances(myinfo,coin,json,remoteaddr,juint(json,"lastheight"),jobj(json,"addresses"),jstr(json,"activecoin"));
}
if ( retstr == 0 )
return(0);
printf("RELAY will return.(%s)\n",retstr);
for (j=0; j<IGUANA_MAXCOINS; j++)
{
if ( (coin= Coins[j]) == 0 )
continue;
for (i=0; i<IGUANA_MAXPEERS; i++)
{
if ( (addr= &coin->peers.active[i]) != 0 && addr->usock >= 0 )
{
if ( addr->supernet != 0 && strcmp(addr->ipaddr,remoteaddr) == 0 )
{
printf("send back rawtx_result addr->supernet.%u to (%s)\n",addr->supernet,addr->ipaddr);
iguana_send_supernet(addr,retstr,0);
free_json(json);
return(retstr);
}
}
if ( 0 && addr->ipbits != 0 )
printf("i.%d (%s) vs (%s) %s\n",i,addr->ipaddr,remoteaddr,coin->symbol);
}
}
}
else
{
if ( strcmp(method,"rawtx_result") == 0 )
{
printf("got rawtx.(%s)\n",jstr(json,"rawtx"));
return(iguana_rawtx_result(myinfo,coin,json,remoteaddr,juint(json,"rawtxtag"),jobj(json,"vins"),jstr(json,"rawtx")));
}
}
}
}
}
if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 )
printf("unhandled bitcoin_hexmsg.(%d) from %s (%s/%s)\n",len,remoteaddr,agent,method);
free_json(json);
return(retstr);
}
void category_init(struct supernet_info *myinfo) void category_init(struct supernet_info *myinfo)
{ {
bits256 pangeahash,instantdexhash,bitcoinhash; bits256 pangeahash,instantdexhash;
category_subscribe(myinfo,GENESIS_PUBKEY,GENESIS_PUBKEY); category_subscribe(myinfo,GENESIS_PUBKEY,GENESIS_PUBKEY);
pangeahash = calc_categoryhashes(0,"pangea",0); pangeahash = calc_categoryhashes(0,"pangea",0);
myinfo->pangea_category = pangeahash; myinfo->pangea_category = pangeahash;
@ -285,9 +217,5 @@ void category_init(struct supernet_info *myinfo)
category_processfunc(instantdexhash,GENESIS_PUBKEY,InstantDEX_hexmsg); category_processfunc(instantdexhash,GENESIS_PUBKEY,InstantDEX_hexmsg);
category_processfunc(instantdexhash,myinfo->myaddr.persistent,InstantDEX_hexmsg); category_processfunc(instantdexhash,myinfo->myaddr.persistent,InstantDEX_hexmsg);
bitcoinhash = calc_categoryhashes(0,"bitcoin",0); basilisks_init(myinfo);
myinfo->bitcoin_category = bitcoinhash;
category_subscribe(myinfo,bitcoinhash,GENESIS_PUBKEY);
category_processfunc(bitcoinhash,GENESIS_PUBKEY,bitcoin_hexmsg);
category_processfunc(bitcoinhash,myinfo->myaddr.persistent,bitcoin_hexmsg);
} }

135
iguana/exchanges/bitcoin.c

@ -158,22 +158,23 @@ int32_t iguana_validatesigs(struct iguana_info *coin,struct iguana_msgvin *vin)
return(0); return(0);
} }
#ifdef bitcoincancalulatebalances
uint64_t bitcoin_parseunspent(struct iguana_info *coin,struct bitcoin_unspent *unspent,double minconfirms,char *account,cJSON *item) uint64_t bitcoin_parseunspent(struct iguana_info *coin,struct bitcoin_unspent *unspent,double minconfirms,char *account,cJSON *item)
{ {
uint8_t addrtype; char *hexstr,*wifstr,coinaddr[64],args[128]; char *hexstr,coinaddr[64];
memset(unspent,0,sizeof(*unspent)); memset(unspent,0,sizeof(*unspent));
if ( jstr(item,"address") != 0 ) if ( jstr(item,"address") != 0 )
{ {
safecopy(coinaddr,jstr(item,"address"),sizeof(coinaddr)); safecopy(coinaddr,jstr(item,"address"),sizeof(coinaddr));
bitcoin_addr2rmd160(&unspent->addrtype,unspent->rmd160,coinaddr); bitcoin_addr2rmd160(&unspent->addrtype,unspent->rmd160,coinaddr);
sprintf(args,"[\"%s\"]",coinaddr); /*sprintf(args,"[\"%s\"]",coinaddr);
wifstr = bitcoind_RPC(0,coin->symbol,coin->chain->serverport,coin->chain->userpass,"dumpprivkey",args); wifstr = bitcoind_RPC(0,coin->symbol,coin->chain->serverport,coin->chain->userpass,"dumpprivkey",args);
if ( wifstr != 0 ) if ( wifstr != 0 )
{ {
bitcoin_wif2priv(&addrtype,&unspent->privkeys[0],wifstr); bitcoin_wif2priv(&addrtype,&unspent->privkeys[0],wifstr);
//printf("wifstr.(%s) -> %s\n",wifstr,bits256_str(str,unspent->privkeys[0])); //printf("wifstr.(%s) -> %s\n",wifstr,bits256_str(str,unspent->privkeys[0]));
free(wifstr); free(wifstr);
} else fprintf(stderr,"error (%s) cant find privkey\n",coinaddr); } else fprintf(stderr,"error (%s) cant find privkey\n",coinaddr);*/
} }
if ( (account == 0 || jstr(item,"account") == 0 || strcmp(account,jstr(item,"account")) == 0) && (minconfirms <= 0 || juint(item,"confirmations") >= minconfirms-SMALLVAL) ) if ( (account == 0 || jstr(item,"account") == 0 || strcmp(account,jstr(item,"account")) == 0) && (minconfirms <= 0 || juint(item,"confirmations") >= minconfirms-SMALLVAL) )
{ {
@ -191,15 +192,15 @@ uint64_t bitcoin_parseunspent(struct iguana_info *coin,struct bitcoin_unspent *u
return(unspent->value); return(unspent->value);
} }
struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct iguana_info *coin,char **retstrp,double *balancep,int32_t *numunspentsp,double minconfirms,char *account) struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct iguana_info *coin,char **retstrp,double *balancep,int32_t *numunspentsp,double minconfirms,char *address)
{ {
char params[128],*retstr; uint64_t value,total = 0; struct bitcoin_unspent *unspents=0; cJSON *utxo; int32_t i,n; char params[128],*retstr; uint64_t value,total = 0; struct bitcoin_unspent *unspents=0; cJSON *utxo; int32_t i,n;
if ( account != 0 && account[0] == 0 )
account = 0;
*numunspentsp = 0; *numunspentsp = 0;
if ( retstrp != 0 ) if ( retstrp != 0 )
*retstrp = 0; *retstrp = 0;
if ( address == 0 )
sprintf(params,"%.0f, 99999999",minconfirms); sprintf(params,"%.0f, 99999999",minconfirms);
else sprintf(params,"%.0f, 99999999, [\"%s\"]",minconfirms,address);
if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"listunspent",params)) != 0 ) if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"listunspent",params)) != 0 )
{ {
printf("sss unspents.(%s)\n",retstr); printf("sss unspents.(%s)\n",retstr);
@ -211,7 +212,7 @@ struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct i
unspents = calloc(*numunspentsp,sizeof(*unspents)); unspents = calloc(*numunspentsp,sizeof(*unspents));
for (i=0; i<*numunspentsp; i++) for (i=0; i<*numunspentsp; i++)
{ {
value = bitcoin_parseunspent(coin,&unspents[n],minconfirms,account,jitem(utxo,i)); value = bitcoin_parseunspent(coin,&unspents[n],minconfirms,0,jitem(utxo,i));
printf("i.%d n.%d value %.8f\n",i,n,dstr(value)); printf("i.%d n.%d value %.8f\n",i,n,dstr(value));
if ( value != 0 ) if ( value != 0 )
{ {
@ -267,13 +268,37 @@ struct bitcoin_unspent *iguana_bestfit(struct iguana_info *coin,struct bitcoin_u
return(vin); return(vin);
} }
struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana_info *coin,int64_t amount,int64_t txfee,char *account) struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana_info *coin,int64_t amount,int64_t txfee,cJSON *addresses,int32_t minconf)
{ {
int32_t i,mode,numunspents,maxinputs = 1024; struct bitcoin_unspent *ptr,*up; int32_t i,n,mode,maxinputs,numunspents,totalunspents = 0; struct bitcoin_unspent *ptr,*up,*ups=0,*u;
struct bitcoin_unspent *ups; struct bitcoin_spend *spend; double balance; int64_t remains,smallest = 0; struct bitcoin_spend *spend; double balance; int64_t remains;
if ( (ups= iguana_unspentsget(myinfo,coin,0,&balance,&numunspents,coin->chain->minconfirms,account)) == 0 ) if ( (n= cJSON_GetArraySize(addresses)) > 0 )
{
for (i=0; i<n; i++)
{
if ( (u= iguana_unspentsget(myinfo,coin,0,&balance,&numunspents,minconf,jstri(addresses,i))) != 0 )
{
if ( ups == 0 )
{
ups = u;
totalunspents = numunspents;
}
else
{
ups = realloc(ups,sizeof(*ups) * (numunspents + totalunspents));
memcpy(&ups[totalunspents],u,sizeof(*ups) * totalunspents);
totalunspents += numunspents;
free(u);
}
}
}
}
else if ( (ups= iguana_unspentsget(myinfo,coin,0,&balance,&totalunspents,minconf,0)) == 0 )
return(0); return(0);
spend = calloc(1,sizeof(*spend) + sizeof(*spend->inputs) * maxinputs); if ( totalunspents == 0 )
return(0);
maxinputs = totalunspents;
spend = calloc(1,sizeof(*spend) + sizeof(*spend->inputs) * totalunspents);
spend->txfee = txfee; spend->txfee = txfee;
remains = txfee + amount; remains = txfee + amount;
spend->satoshis = remains; spend->satoshis = remains;
@ -281,39 +306,101 @@ struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana
for (i=0; i<maxinputs; i++,ptr++) for (i=0; i<maxinputs; i++,ptr++)
{ {
for (mode=1; mode>=0; mode--) for (mode=1; mode>=0; mode--)
if ( (up= iguana_bestfit(coin,ups,numunspents,remains,mode)) != 0 ) if ( (up= iguana_bestfit(coin,ups,totalunspents,remains,mode)) != 0 )
break; break;
if ( up != 0 ) if ( up != 0 )
{ {
if ( smallest == 0 || up->value < smallest )
{
smallest = up->value;
memcpy(spend->change160,up->rmd160,sizeof(spend->change160));
}
spend->input_satoshis += up->value; spend->input_satoshis += up->value;
spend->inputs[spend->numinputs++] = *up; spend->inputs[spend->numinputs++] = *up;
// todo: update a vins array
if ( spend->input_satoshis >= spend->satoshis ) if ( spend->input_satoshis >= spend->satoshis )
{ {
// numinputs 1 -> (1.00074485 - spend 0.41030880) = net 0.59043605 vs amount 0.40030880 change 0.40030880 -> txfee 0.01000000 vs chainfee 0.01000000
spend->change = (spend->input_satoshis - spend->satoshis) - txfee; spend->change = (spend->input_satoshis - spend->satoshis) - txfee;
printf("numinputs %d -> (%.8f - spend %.8f) = change %.8f -> txfee %.8f vs chainfee %.8f\n",spend->numinputs,dstr(spend->input_satoshis),dstr(spend->satoshis),dstr(spend->change),dstr(spend->input_satoshis - spend->change - spend->satoshis),dstr(txfee)); printf("numinputs %d -> (%.8f - spend %.8f) = change %.8f -> txfee %.8f vs chainfee %.8f\n",spend->numinputs,dstr(spend->input_satoshis),dstr(spend->satoshis),dstr(spend->change),dstr(spend->input_satoshis - spend->change - spend->satoshis),dstr(txfee));
break; break;
} }
memset(up,0,sizeof(*up));
remains -= up->value; remains -= up->value;
} else break; } else break;
} }
if ( spend->input_satoshis >= spend->satoshis ) if ( spend->input_satoshis >= spend->satoshis )
{ {
spend = realloc(spend,sizeof(*spend) + sizeof(*spend->inputs) * spend->numinputs); spend = realloc(spend,sizeof(*spend) + sizeof(*spend->inputs) * spend->numinputs);
free(ups);
return(spend); return(spend);
} }
else else
{ {
free(spend); free(spend);
free(ups);
return(0); return(0);
} }
} }
cJSON *bitcoin_vout(uint64_t satoshis,char *paymentscriptstr)
{
cJSON *item,*skey;
item = cJSON_CreateObject();
jadd64bits(item,"satoshis",satoshis);
skey = cJSON_CreateObject();
jaddstr(skey,"hex",paymentscriptstr);
//printf("addoutput.(%s %s)\n",hexstr,jprint(skey,0));
jadd(item,"scriptPubkey",skey);
return(item);
}
char *bitcoin_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJSON **vinsp,int64_t satoshis,char *paymentscriptstr,char *changeaddr,int64_t txfee,cJSON *addresses,int32_t minconf,uint32_t locktime)
{
uint8_t addrtype,rmd160[20],script[512]; int32_t i,scriptlen; char *params,*rawtx=0; cJSON *item,*array,*vins=0,*vouts=0; struct bitcoin_spend *spend; char scriptstr[512],*voutstr;
*vinsp = 0;
if ( (spend= iguana_spendset(myinfo,coin,satoshis,txfee*2,addresses,minconf)) == 0 )
return(0);
if ( spend->input_satoshis >= satoshis+txfee*2 )
{
vins = cJSON_CreateArray();
for (i=0; i<spend->numinputs; i++)
{
item = cJSON_CreateObject();
jaddbits256(item,"txid",spend->inputs[i].txid);
jaddnum(item,"vout",spend->inputs[i].vout);
jaddi(vins,item);
}
vouts = cJSON_CreateArray();
jaddi(vouts,bitcoin_vout(satoshis,paymentscriptstr));
if ( spend->change > 0 )
{
if ( iguana_addressvalidate(coin,&addrtype,changeaddr) < 0 )
{
free(spend);
printf("illegal destination address.(%s)\n",changeaddr);
return(0);
}
bitcoin_addr2rmd160(&addrtype,rmd160,changeaddr);
scriptlen = bitcoin_standardspend(script,0,rmd160);
init_hexbytes_noT(scriptstr,script,scriptlen);
jaddi(vouts,bitcoin_vout(satoshis,scriptstr));
}
bitcoin_addr2rmd160(&addrtype,rmd160,myinfo->myaddr.BTC);
scriptlen = bitcoin_standardspend(script,0,rmd160);
jaddi(vouts,bitcoin_vout(satoshis,scriptstr));
voutstr = jprint(vouts,1);
voutstr[0] = '{', voutstr[strlen(voutstr)-1] = '}';
array = cJSON_CreateArray();
jaddi(array,jduplicate(vins));
jaddi(array,cJSON_Parse(voutstr)), free(voutstr);
params = jprint(array,1);
rawtx = bitcoind_passthru(coin->name,coin->chain->serverport,coin->chain->userpass,"createrawtransaction",params);
free(params);
}
*vinsp = vins;
free(spend);
// add sigtxid to vins
if ( locktime != 0 )
printf("need to patch locktime\n");
return(rawtx);
}
#endif
#define EXCHANGE_NAME "bitcoin" #define EXCHANGE_NAME "bitcoin"
#define UPDATE bitcoin ## _price #define UPDATE bitcoin ## _price
#define SUPPORTS bitcoin ## _supports #define SUPPORTS bitcoin ## _supports
@ -364,19 +451,19 @@ char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr
cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson) cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson)
{ {
double balance; char *retstr; int32_t i,numunspents,minconfirms; struct iguana_info *coin; double balance; int32_t i,minconfirms; struct iguana_info *coin; // char *retstr,numunspents;
struct supernet_info *myinfo; struct bitcoin_unspent *unspents; cJSON *item,*retjson,*utxo; struct supernet_info *myinfo; cJSON *retjson;// item,*utxo; //struct bitcoin_unspent *unspents;
retjson = cJSON_CreateArray(); retjson = cJSON_CreateArray();
myinfo = SuperNET_accountfind(argjson); myinfo = SuperNET_accountfind(argjson);
for (i=0; i<IGUANA_MAXCOINS; i++) for (i=0; i<IGUANA_MAXCOINS; i++)
{ {
if ( (coin= Coins[i]) != 0 && coin->chain->serverport[0] != 0 ) if ( (coin= Coins[i]) != 0 )//&& coin->chain->serverport[0] != 0 )
{ {
balance = 0.; balance = 0.;
minconfirms = juint(argjson,"minconfirms"); minconfirms = juint(argjson,"minconfirms");
if ( minconfirms < coin->minconfirms ) if ( minconfirms < coin->minconfirms )
minconfirms = coin->minconfirms; minconfirms = coin->minconfirms;
if ( (unspents= iguana_unspentsget(myinfo,coin,&retstr,&balance,&numunspents,minconfirms,0)) != 0 ) /*if ( (unspents= iguana_unspentsget(myinfo,coin,&retstr,&balance,&numunspents,minconfirms,0)) != 0 )
{ {
item = cJSON_CreateObject(); item = cJSON_CreateObject();
jaddnum(retjson,"balance",balance); jaddnum(retjson,"balance",balance);
@ -391,7 +478,7 @@ cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson)
} }
free(unspents); free(unspents);
jadd(retjson,coin->symbol,item); jadd(retjson,coin->symbol,item);
} }*/
} }
} }
return(retjson); return(retjson);

2
iguana/iguana.sources

@ -1,2 +1,2 @@
SOURCES := SuperNET.c iguana_bundles.c iguana_stake.c iguana_interpreter.c mini-gmp.c main.c iguana_payments.c iguana_spendvectors.c iguana_sign.c iguana_txidfind.c iguana_realtime.c iguana_volatiles.c peggy_price.c SuperNET_category.c iguana_chains.c iguana_ramchain.c iguana_secp.c pangea_api.c peggy_ramkv.c SuperNET_hexmsg.c iguana_exchanges.c iguana_recv.c pangea_bets.c peggy_serdes.c SuperNET_keys.c iguana_rpc.c pangea_hand.c peggy_tx.c cards777.c iguana_init.c iguana_scripts.c pangea_json.c peggy_txind.c iguana777.c iguana_instantdex.c iguana_tradebots.c pangea_summary.c peggy_update.c iguana_accept.c iguana_json.c iguana_tx.c peggy.c poker.c iguana_bitmap.c iguana_msg.c iguana_unspents.c peggy_accts.c ramchain_api.c iguana_blocks.c iguana_peers.c iguana_wallet.c peggy_consensus.c secp256k1/src/secp256k1.c SOURCES := SuperNET.c iguana_bundles.c iguana_stake.c iguana_interpreter.c mini-gmp.c main.c iguana_payments.c iguana_spendvectors.c iguana_sign.c iguana_txidfind.c iguana_realtime.c iguana_volatiles.c peggy_price.c SuperNET_category.c iguana_chains.c iguana_ramchain.c iguana_secp.c pangea_api.c peggy_ramkv.c SuperNET_hexmsg.c iguana_exchanges.c iguana_recv.c pangea_bets.c peggy_serdes.c SuperNET_keys.c iguana_rpc.c pangea_hand.c peggy_tx.c cards777.c iguana_init.c iguana_scripts.c pangea_json.c peggy_txind.c iguana777.c iguana_instantdex.c iguana_tradebots.c pangea_summary.c peggy_update.c iguana_accept.c iguana_json.c iguana_tx.c peggy.c poker.c iguana_bitmap.c iguana_msg.c iguana_unspents.c peggy_accts.c ramchain_api.c iguana_blocks.c iguana_peers.c iguana_wallet.c peggy_consensus.c ../basilisk/basilisk.c secp256k1/src/secp256k1.c

12
iguana/iguana777.c

@ -691,7 +691,7 @@ void iguana_coinloop(void *arg)
{ {
if ( coin->MAXPEERS > IGUANA_MAXPEERS ) if ( coin->MAXPEERS > IGUANA_MAXPEERS )
coin->MAXPEERS = IGUANA_MAXPEERS; coin->MAXPEERS = IGUANA_MAXPEERS;
if ( coin->MAXPEERS < IGUANA_MINPEERS ) if ( coin->MAXPEERS > 1 && coin->MAXPEERS < IGUANA_MINPEERS )
coin->MAXPEERS = IGUANA_MAXPEERS; coin->MAXPEERS = IGUANA_MAXPEERS;
#ifdef __PNACL__ #ifdef __PNACL__
if ( coin->MAXPEERS > 64 ) if ( coin->MAXPEERS > 64 )
@ -729,7 +729,7 @@ void iguana_coinloop(void *arg)
} }
if ( coin->bindsock >= 0 ) if ( coin->bindsock >= 0 )
{ {
if ( coin->peers.numranked < (7*coin->MAXPEERS/8) && now > coin->lastpossible ) if ( coin->MAXPEERS > 1 && coin->peers.numranked < (7*coin->MAXPEERS/8) && now > coin->lastpossible )
{ {
//fprintf(stderr,"possible\n"); //fprintf(stderr,"possible\n");
if ( coin->peers.numranked > 0 && (now % 60) == 0 ) if ( coin->peers.numranked > 0 && (now % 60) == 0 )
@ -739,21 +739,21 @@ void iguana_coinloop(void *arg)
} }
else else
{ {
if ( coin->peers.numranked < ((7*coin->MAXPEERS)>>3) && now > coin->lastpossible ) if ( coin->MAXPEERS > 1 && coin->peers.numranked < ((7*coin->MAXPEERS)>>3) && now > coin->lastpossible )
{ {
if ( coin->peers.numranked > 0 && (now % 60) == 0 ) if ( coin->peers.numranked > 0 && (now % 60) == 0 )
iguana_send_ping(coin,coin->peers.ranked[rand() % coin->peers.numranked]); iguana_send_ping(coin,coin->peers.ranked[rand() % coin->peers.numranked]);
coin->lastpossible = iguana_possible_peer(coin,0); // tries to connect to new peers coin->lastpossible = iguana_possible_peer(coin,0); // tries to connect to new peers
} }
} }
if ( now > coin->peers.lastmetrics+10 ) if ( coin->MAXPEERS > 1 && now > coin->peers.lastmetrics+10 )
{ {
//fprintf(stderr,"metrics\n"); //fprintf(stderr,"metrics\n");
coin->peers.lastmetrics = iguana_updatemetrics(myinfo,coin); // ranks peers coin->peers.lastmetrics = iguana_updatemetrics(myinfo,coin); // ranks peers
} }
if ( coin->longestchain+10000 > coin->blocks.maxbits ) if ( coin->longestchain+10000 > coin->blocks.maxbits )
iguana_recvalloc(coin,coin->longestchain + 100000); iguana_recvalloc(coin,coin->longestchain + 100000);
if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 ) if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 || coin->MAXPEERS == 1 )
flag += iguana_processrecv(myinfo,coin); flag += iguana_processrecv(myinfo,coin);
iguana_jsonQ(); iguana_jsonQ();
} }
@ -796,6 +796,8 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers,
coin->myservices = services; coin->myservices = services;
coin->initialheight = initialheight; coin->initialheight = initialheight;
coin->mapflags = mapflags; coin->mapflags = mapflags;
coin->protocol = IGUANA_PROTOCOL_BITCOIN;
basilisk_functions(coin);
mult = (strcmp("BTC",coin->symbol) != 0) ? 8 : 8; mult = (strcmp("BTC",coin->symbol) != 0) ? 8 : 8;
maxval = IGUANA_MAXPENDBUNDLES; maxval = IGUANA_MAXPENDBUNDLES;
if ( (coin->txfee= jdouble(json,"txfee") * SATOSHIDEN) == 0 ) if ( (coin->txfee= jdouble(json,"txfee") * SATOSHIDEN) == 0 )

24
iguana/iguana777.h

@ -17,6 +17,7 @@
#define iguana777_net_h #define iguana777_net_h
#include "../crypto777/OS_portable.h" #include "../crypto777/OS_portable.h"
#include "SuperNET.h" #include "SuperNET.h"
#include "../basilisk/basilisk.h"
#define SPARSECOUNT(x) ((x) << 1) #define SPARSECOUNT(x) ((x) << 1)
@ -96,6 +97,13 @@ struct iguana_txdatabits { uint64_t addrind:IGUANA_LOG2MAXPEERS,filecount:10,fpo
#define IGUANA_SUBDIRDIVISOR 28000 #define IGUANA_SUBDIRDIVISOR 28000
#define IGUANA_PROTOCOL_BITCOIN 'b'
#define IGUANA_PROTOCOL_NXT 'n'
#define IGUANA_PROTOCOL_ETHER 'e'
#define IGUANA_PROTOCOL_LISK 'l'
#define IGUANA_PROTOCOL_WAVES 'w'
#define IGUANA_PROTOCOL_IOTA 'i'
#ifdef __PNACL #ifdef __PNACL
void PNACL_message(const char* format, ...); void PNACL_message(const char* format, ...);
#endif #endif
@ -337,7 +345,7 @@ struct iguana_blocks
char coin[8]; char coin[8];
struct iguanakv *db; struct iguanakv *db;
struct iguana_block *hash; struct iguana_blockRO *RO; int32_t maxbits; struct iguana_block *hash; struct iguana_blockRO *RO; int32_t maxbits;
int32_t maxblocks,initblocks,hashblocks,issuedblocks,recvblocks,emitblocks,parsedblocks,dirty; int32_t maxblocks,initblocks,hashblocks,pending,issuedblocks,recvblocks,emitblocks,parsedblocks,dirty;
struct iguana_block hwmchain; struct iguana_block hwmchain;
}; };
@ -489,8 +497,12 @@ struct iguana_monitorinfo { bits256 txid; int32_t numreported; uint8_t peerbits[
struct iguana_info struct iguana_info
{ {
char name[64],symbol[8],statusstr[512],scriptsfname[2][512]; char name[64],symbol[8],protocol,statusstr[512],scriptsfname[2][512];
struct iguana_peers peers; struct iguana_peer internaladdr; struct iguana_peers peers; struct iguana_peer internaladdr;
char *(*basilisk_rawtx)(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *changeaddr,uint64_t txfee,cJSON *addresses,int32_t minconf,char *spendscriptstr,int32_t timeoutmillis);
int64_t (*basilisk_balances)(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **arrayp,int32_t lastheight,int32_t minconf,cJSON *addresses,int32_t timeoutmillis);
int64_t (*basilisk_value)(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,bits256 txid,int32_t vout,char *coinaddr,int32_t timeoutmillis);
uint32_t fastfind; FILE *fastfps[0x100]; uint8_t *fast[0x100]; int32_t *fasttables[0x100]; long fastsizes[0x100]; uint32_t fastfind; FILE *fastfps[0x100]; uint8_t *fast[0x100]; int32_t *fasttables[0x100]; long fastsizes[0x100];
uint64_t instance_nonce,myservices,totalsize,totalrecv,totalpackets,sleeptime; uint64_t instance_nonce,myservices,totalsize,totalrecv,totalpackets,sleeptime;
int64_t mining,totalfees,TMPallocated,MAXRECVCACHE,MAXMEM,PREFETCHLAG,estsize,activebundles; int64_t mining,totalfees,TMPallocated,MAXRECVCACHE,MAXMEM,PREFETCHLAG,estsize,activebundles;
@ -825,7 +837,7 @@ cJSON *iguana_blockjson(struct iguana_info *coin,struct iguana_block *block,int3
//int32_t iguana_ver(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen,uint8_t *pubkey); //int32_t iguana_ver(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen,uint8_t *pubkey);
void calc_rmd160_sha256(uint8_t rmd160[20],uint8_t *data,int32_t datalen); void calc_rmd160_sha256(uint8_t rmd160[20],uint8_t *data,int32_t datalen);
int32_t bitcoin_checklocktimeverify(uint8_t *script,int32_t n,uint32_t locktime); int32_t bitcoin_checklocktimeverify(uint8_t *script,int32_t n,uint32_t locktime);
struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana_info *coin,int64_t satoshis,int64_t insurance,char *account); struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana_info *coin,int64_t amount,int64_t txfee,cJSON *addresses,int32_t minconf);
cJSON *bitcoin_hex2json(struct iguana_info *coin,bits256 *txidp,struct iguana_msgtx *msgtx,char *txbytes,uint8_t *extrapace,int32_t extralen); cJSON *bitcoin_hex2json(struct iguana_info *coin,bits256 *txidp,struct iguana_msgtx *msgtx,char *txbytes,uint8_t *extrapace,int32_t extralen);
cJSON *iguana_signtx(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,char **signedtxp,struct bitcoin_spend *spend,cJSON *txobj,cJSON *vins); cJSON *iguana_signtx(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,char **signedtxp,struct bitcoin_spend *spend,cJSON *txobj,cJSON *vins);
void iguana_addscript(struct iguana_info *coin,cJSON *dest,uint8_t *script,int32_t scriptlen,char *fieldname); void iguana_addscript(struct iguana_info *coin,cJSON *dest,uint8_t *script,int32_t scriptlen,char *fieldname);
@ -841,7 +853,7 @@ int32_t bitcoin_verify(void *ctx,uint8_t *sig,int32_t siglen,bits256 txhash2,uin
char *bitcoin_json2hex(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,cJSON *txjson,struct vin_info *V); char *bitcoin_json2hex(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,cJSON *txjson,struct vin_info *V);
int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr); int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr);
char *issue_startForging(struct supernet_info *myinfo,char *secret); char *issue_startForging(struct supernet_info *myinfo,char *secret);
struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct iguana_info *coin,char **retstrp,double *balancep,int32_t *numunspentsp,double minconfirms,char *account); struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct iguana_info *coin,char **retstrp,double *balancep,int32_t *numunspentsp,double minconfirms,char *address);
void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson); void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson);
int32_t iguana_pkhasharray(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,int64_t *totalp,struct iguana_pkhash *P,int32_t max,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t lastheight,int64_t *unspents,int32_t *numunspentsp,int32_t maxunspents); int32_t iguana_pkhasharray(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,int64_t *totalp,struct iguana_pkhash *P,int32_t max,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t lastheight,int64_t *unspents,int32_t *numunspentsp,int32_t maxunspents);
long iguana_spentsfile(struct iguana_info *coin,int32_t n); long iguana_spentsfile(struct iguana_info *coin,int32_t n);
@ -991,7 +1003,6 @@ void instantdex_FSMinit();
void iguana_unspentslock(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *vins); void iguana_unspentslock(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *vins);
char *iguana_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJSON **vinsp,cJSON *txobj,int64_t satoshis,char *changeaddr,int64_t txfee,cJSON *addresses,int32_t minconf); char *iguana_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJSON **vinsp,cJSON *txobj,int64_t satoshis,char *changeaddr,int64_t txfee,cJSON *addresses,int32_t minconf);
char *iguana_signrawtx(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *signedtxidp,int32_t *completedp,cJSON *vins,char *rawtx,cJSON *privkey); char *iguana_signrawtx(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *signedtxidp,int32_t *completedp,cJSON *vins,char *rawtx,cJSON *privkey);
char *iguana_pollrawtx(queue_t *Q,cJSON **vinsp,uint32_t rawtxtag,double expiration);
bits256 scrypt_blockhash(const void *input); bits256 scrypt_blockhash(const void *input);
bits256 iguana_calcblockhash(int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len),uint8_t *serialized,int32_t len); bits256 iguana_calcblockhash(int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len),uint8_t *serialized,int32_t len);
uint32_t iguana_targetbits(struct iguana_info *coin,struct iguana_block *hwmchain,struct iguana_block *prev,struct iguana_block *prev2,int32_t PoSflag); uint32_t iguana_targetbits(struct iguana_info *coin,struct iguana_block *hwmchain,struct iguana_block *prev,struct iguana_block *prev2,int32_t PoSflag);
@ -1000,6 +1011,9 @@ void instantdex_eventfree(struct bitcoin_eventitem *ptr);
struct iguana_monitorinfo *iguana_txidmonitor(struct iguana_info *coin,bits256 txid); struct iguana_monitorinfo *iguana_txidmonitor(struct iguana_info *coin,bits256 txid);
struct iguana_monitorinfo *iguana_txidreport(struct iguana_info *coin,bits256 txid,struct iguana_peer *addr); struct iguana_monitorinfo *iguana_txidreport(struct iguana_info *coin,bits256 txid,struct iguana_peer *addr);
double iguana_txidstatus(struct iguana_info *coin,bits256 txid); double iguana_txidstatus(struct iguana_info *coin,bits256 txid);
void basilisk_functions(struct iguana_info *coin);
char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params);
char *bitcoin_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJSON **vinsp,int64_t satoshis,char *paymentscriptstr,char *changeaddr,int64_t txfee,cJSON *addresses,int32_t minconf,uint32_t locktime);
extern int32_t HDRnet,netBLOCKS; extern int32_t HDRnet,netBLOCKS;

2
iguana/iguana_blocks.c

@ -572,6 +572,8 @@ struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_bl
} }
} }
block->mainchain = 1; block->mainchain = 1;
if ( coin->blocks.pending > 0 )
coin->blocks.pending--;
/*if ( block->serdata != 0 ) /*if ( block->serdata != 0 )
{ {
printf(" call process_iguanablock2.%p ht.%d nbits.%08x\n",block->serdata,block->height,*(uint32_t *)&block->serdata[72]); printf(" call process_iguanablock2.%p ht.%d nbits.%08x\n",block->serdata,block->height,*(uint32_t *)&block->serdata[72]);

4
iguana/iguana_bundles.c

@ -1411,8 +1411,8 @@ void iguana_bundlestats(struct iguana_info *coin,char *str,int32_t lag)
static FILE *logfp; static FILE *logfp;
if ( logfp == 0 ) if ( logfp == 0 )
logfp = fopen("debug.log","wb"); logfp = fopen("debug.log","wb");
if ( logfp != 0 ) //if ( logfp != 0 )
fprintf(logfp,"%s bQ.%d %d:%02d:%02d stuck.%d max.%d\n",str,queue_size(&bundlesQ),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,coin->stucktime!=0?(uint32_t)time(NULL) - coin->stucktime:0,coin->maxstuck); printf("%s bQ.%d %d:%02d:%02d stuck.%d max.%d\n",str,queue_size(&bundlesQ),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,coin->stucktime!=0?(uint32_t)time(NULL) - coin->stucktime:0,coin->maxstuck);
strcpy(coin->lastdispstr,str); strcpy(coin->lastdispstr,str);
//if ( (rand() % 100) == 0 ) //if ( (rand() % 100) == 0 )
// myallocated(0,0); // myallocated(0,0);

276
iguana/iguana_payments.c

@ -367,7 +367,7 @@ char *iguana_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJS
void iguana_unspentslock(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *vins) void iguana_unspentslock(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *vins)
{ {
uint32_t spent_unspentind; char coinaddr[64]; int16_t spent_hdrsi; int32_t i,RTspentflag,num; uint32_t spent_unspentind; char coinaddr[64]; int16_t spent_hdrsi; int32_t i,RTspentflag,num;
if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 ) if ( coin->MAXPEERS == 1 || coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 )
{ {
num = cJSON_GetArraySize(vins); num = cJSON_GetArraySize(vins);
for (i=0; i<num; i++) for (i=0; i<num; i++)
@ -378,136 +378,7 @@ void iguana_unspentslock(struct supernet_info *myinfo,struct iguana_info *coin,c
} }
} }
cJSON *iguana_requestjson(struct supernet_info *myinfo,cJSON *hexjson) char *sendtoaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,char *coinaddr,uint64_t satoshis,uint64_t txfee,char *comment,char *comment2,int32_t minconf,char *account)
{
char *str,*buf; cJSON *retjson;
str = jprint(hexjson,1);
buf = malloc(strlen(str)*2 + 1);
init_hexbytes_noT(buf,(uint8_t *)str,(int32_t)strlen(str));
free(str);
retjson = cJSON_CreateObject();
jaddstr(retjson,"agent","SuperNET");
jaddstr(retjson,"method","DHT");
jaddnum(retjson,"request",1);
jaddnum(retjson,"plaintext",1);
jaddbits256(retjson,"categoryhash",myinfo->bitcoin_category);
jaddnum(retjson,"timeout",5000);
jaddstr(retjson,"hexmsg",buf);
free(buf);
return(retjson);
}
char *iguana_pollrawtx(queue_t *Q,cJSON **vinsp,uint32_t rawtxtag,double expiration)
{
struct rawtx_queue *ptr; char *rawtx;
while ( OS_milliseconds() < expiration )
{
usleep(100000);
if ( (ptr= queue_dequeue(Q,0)) != 0 )
{
if ( rawtxtag == ptr->rawtxtag )
{
rawtx = clonestr(ptr->rawtx);
//printf("got RAWTX.(%s)\n",rawtx);
if ( vinsp != 0 )
*vinsp = ptr->vins;
else if ( ptr->vins != 0 )
free_json(ptr->vins);
free(ptr);
return(rawtx);
}
else
{
if ( ptr->vins != 0 )
free_json(ptr->vins);
free(ptr);
}
}
}
return(0);
}
char *iguana_request_andwait(struct supernet_info *myinfo,queue_t *Q,cJSON **vinsp,cJSON *reqjson,uint32_t rawtxtag,int32_t timeout)
{
struct rawtx_queue *ptr; int32_t i,j,n; struct iguana_peer *addr; double expiration; struct iguana_info *coin; char *reqstr; cJSON *tmpjson;
if ( vinsp != 0 )
*vinsp = 0;
tmpjson = iguana_requestjson(myinfo,reqjson);
reqstr = jprint(tmpjson,1);
while ( (ptr= queue_dequeue(Q,0)) != 0 )
{
if ( ptr->vins != 0 )
free_json(ptr->vins);
free(ptr);
}
expiration = OS_milliseconds() + ((timeout == 0) ? 15000 : timeout);
for (i=n=0; i<IGUANA_MAXCOINS; i++)
{
if ( (coin= Coins[i]) != 0 )
{
for (j=0; j<IGUANA_MAXPEERS; j++)
{
if ( (addr= &coin->peers.active[j]) != 0 && addr->supernet != 0 && addr->usock >= 0 )
{
iguana_send_supernet(addr,reqstr,0);
if ( n++ > 8 )
break;
}
}
}
}
return(iguana_pollrawtx(Q,vinsp,rawtxtag,expiration));
}
char *iguana_rawtxissue(struct supernet_info *myinfo,uint32_t rawtxtag,char *symbol,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *changeaddr,uint64_t txfee,cJSON *addresses,int32_t minconf,char *spendscriptstr,int32_t timeout)
{
uint8_t buf[IGUANA_MAXSCRIPTSIZE]; int32_t spendlen; cJSON *hexjson,*valsobj,*txobj = 0; char *retstr,*rawtx = 0; struct iguana_info *coin;
*vinsp = 0;
if ( (coin= iguana_coinfind(symbol)) != 0 && (coin->VALIDATENODE != 0 || coin->RELAYNODE != 0) )
{
if ( (txobj= bitcoin_txcreate(coin,locktime)) != 0 )
{
spendlen = (int32_t)strlen(spendscriptstr) >> 1;
decode_hex(buf,spendlen,spendscriptstr);
bitcoin_txoutput(coin,txobj,buf,spendlen,satoshis);
if ( (rawtx= iguana_calcrawtx(myinfo,coin,vinsp,txobj,satoshis,changeaddr,txfee,addresses,minconf)) != 0 )
{
if ( *vinsp != 0 )
{
free_json(txobj);
//printf("return rawtx.(%s) vins.%p\n",rawtx,*vinsp);
return(rawtx);
} else free(rawtx);
}
}
}
if ( txobj != 0 )
free_json(txobj);
if ( addresses != 0 )
{
hexjson = cJSON_CreateObject();
jaddstr(hexjson,"changeaddr",changeaddr);
jaddstr(hexjson,"spendscriptstr",spendscriptstr);
jadd(hexjson,"addresses",jduplicate(addresses));
valsobj = cJSON_CreateObject();
jaddnum(valsobj,"rawtxtag",rawtxtag);
jaddstr(valsobj,"coin",symbol);
jadd64bits(valsobj,"amount",satoshis);
jadd64bits(valsobj,"txfee",txfee);
jaddnum(valsobj,"minconf",minconf);
jaddnum(valsobj,"locktime",locktime);
jadd(hexjson,"vals",valsobj);
jaddstr(hexjson,"agent","iguana");
jaddstr(hexjson,"method","rawtx");
//{\"agent\":\"iguana\",\"method\":\"rawtx\",\"changeaddr\":\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\",\"addresses\":[\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\"],\"vals\":{\"coin\":\"BTCD\",\"amount\":\"10000000\"},\"spendscriptstr\":\"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac\"}
if ( (retstr= iguana_request_andwait(myinfo,&myinfo->rawtxQ,vinsp,hexjson,rawtxtag,timeout)) == 0 )
return(clonestr("{\"error\":\"timeout waiting for remote request\"}"));
else return(retstr);
}
return(0);
}
char *sendtoaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,uint64_t satoshis,uint64_t txfee,char *comment,char *comment2,int32_t minconf,char *account)
{ {
uint8_t addrtype,spendscript[1024],rmd160[20]; int32_t completed; char spendscriptstr[4096],*rawtx=0,*signedtx = 0; bits256 signedtxid,senttxid; cJSON *retjson,*vins,*addresses; uint32_t spendlen,locktime = 0; struct iguana_waddress *waddr; uint8_t addrtype,spendscript[1024],rmd160[20]; int32_t completed; char spendscriptstr[4096],*rawtx=0,*signedtx = 0; bits256 signedtxid,senttxid; cJSON *retjson,*vins,*addresses; uint32_t spendlen,locktime = 0; struct iguana_waddress *waddr;
//sendtoaddress <bitcoinaddress> <amount> [comment] [comment-to] <amount> is a real and is rounded to 8 decimal places. Returns the transaction ID <txid> if successful. Y //sendtoaddress <bitcoinaddress> <amount> [comment] [comment-to] <amount> is a real and is rounded to 8 decimal places. Returns the transaction ID <txid> if successful. Y
@ -525,7 +396,7 @@ char *sendtoaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *
bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr);
spendlen = bitcoin_standardspend(spendscript,0,rmd160); spendlen = bitcoin_standardspend(spendscript,0,rmd160);
init_hexbytes_noT(spendscriptstr,spendscript,spendlen); init_hexbytes_noT(spendscriptstr,spendscript,spendlen);
if ( (rawtx= iguana_rawtxissue(myinfo,rand(),coin->symbol,&vins,locktime,satoshis,coin->changeaddr,txfee,addresses,minconf,spendscriptstr,60000)) != 0 ) if ( (rawtx= basilisk_issuerawtx(myinfo,remoteaddr,0,coin->symbol,&vins,locktime,satoshis,spendscriptstr,coin->changeaddr,txfee,minconf,addresses,0)) != 0 )
{ {
if ( (signedtx= iguana_signrawtx(myinfo,coin,&signedtxid,&completed,vins,rawtx,0)) != 0 ) if ( (signedtx= iguana_signrawtx(myinfo,coin,&signedtxid,&completed,vins,rawtx,0)) != 0 )
{ {
@ -557,144 +428,9 @@ char *sendtoaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *
return(clonestr("{\"error\":\"need address and amount\"}")); return(clonestr("{\"error\":\"need address and amount\"}"));
} }
char *iguana_createrawtx(struct supernet_info *myinfo,uint32_t rawtxtag,char *symbol,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *spendscriptstr,char *changeaddr,int64_t txfee,int32_t minconf,cJSON *addresses,int32_t timeout)
{
char *rawtx=0;
*vinsp = 0;
if ( (rawtx= iguana_rawtxissue(myinfo,rawtxtag,symbol,vinsp,locktime,satoshis,changeaddr,txfee,addresses,minconf,spendscriptstr,timeout)) != 0 )
{
/*if ( *vinsp != 0 && (coin= iguana_coinfind(symbol)) != 0 && (signedtx= iguana_signrawtx(myinfo,coin,&signedtxid,&completed,*vinsp,rawtx)) != 0 )
{
iguana_unspentslock(myinfo,coin,*vinsp);
retjson = cJSON_CreateObject();
jaddbits256(retjson,"result",signedtxid);
jaddstr(retjson,"signedtx",signedtx);
jadd(retjson,"complete",completed != 0 ? jtrue() : jfalse());
free(rawtx);
free(signedtx);
return(jprint(retjson,1));
}*/
return(rawtx);
}
return(0);
}
#include "../includes/iguana_apidefs.h" #include "../includes/iguana_apidefs.h"
#include "../includes/iguana_apideclares.h" #include "../includes/iguana_apideclares.h"
INT_ARRAY_STRING(iguana,balances,lastheight,addresses,activecoin)
{
uint64_t amount,total = 0; cJSON *item,*result,*array,*retjson,*hexjson; int32_t i,n,minconf=0; char *retstr,*balancestr,*coinaddr;
retjson = cJSON_CreateObject();
if ( activecoin != 0 && activecoin[0] != 0 && (coin= iguana_coinfind(activecoin)) != 0 )
{
if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 )
{
array = cJSON_CreateArray();
if ( (n= cJSON_GetArraySize(addresses)) > 0 )
{
for (i=0; i<n; i++)
{
coinaddr = jstri(addresses,i);
if ( (balancestr= iguana_balance(IGUANA_CALLARGS,activecoin,coinaddr,lastheight,minconf)) != 0 )
{
if ( (result= cJSON_Parse(balancestr)) != 0 )
{
if ( jobj(result,"balance") != 0 )
{
item = cJSON_CreateObject();
amount = SATOSHIDEN * jdouble(result,"balance");
total += amount;
jaddnum(item,coinaddr,dstr(amount));
jaddi(array,item);
}
free_json(result);
}
free(balancestr);
}
}
}
jadd(retjson,"balances",array);
jaddnum(retjson,"total",dstr(total));
if ( lastheight != 0 )
jaddnum(retjson,"lastheight",lastheight);
if ( remoteaddr != 0 && remoteaddr[0] != 0 && strcmp(remoteaddr,"127.0.0.1") != 0 )
{
//printf("remote req.(%s)\n",jprint(retjson,0));
hexjson = cJSON_CreateObject();
jaddstr(hexjson,"rawtx",jprint(retjson,1));
jaddstr(hexjson,"agent","iguana");
jaddstr(hexjson,"method","rawtx_result");
jaddstr(hexjson,"activecoin",activecoin);
jaddnum(hexjson,"rawtxtag",lastheight);
retjson = iguana_requestjson(myinfo,hexjson);
} else jaddstr(retjson,"result","success");
return(jprint(retjson,1));
}
else if ( remoteaddr == 0 || remoteaddr[0] == 0 || strcmp(remoteaddr,"127.0.0.1") == 0 )
{
if ( (retstr= iguana_request_andwait(myinfo,&myinfo->rawtxQ,0,json,lastheight,juint(json,"timeout"))) == 0 )
return(clonestr("{\"error\":\"timeout waiting for remote request\"}"));
else return(retstr);
} else return(clonestr("{\"error\":\"invalid remoterequest when not relaynode\"}"));
} else return(clonestr("{\"error\":\"invalid request for inactive coin\"}"));
}
STRING_ARRAY_OBJ_STRING(iguana,rawtx,changeaddr,addresses,vals,spendscriptstr)
{
cJSON *vins=0,*retjson,*hexjson,*valsobj; char *rawtx=0,*symbol=0; int64_t txfee,satoshis; uint32_t locktime,minconf,rawtxtag;
//printf("RAWTX changeaddr.%s (%s) remote.(%s)\n",changeaddr==0?"":changeaddr,jprint(json,0),remoteaddr);
retjson = cJSON_CreateObject();
if ( spendscriptstr != 0 && spendscriptstr[0] != 0 && (symbol= jstr(vals,"coin")) != 0 )
{
minconf = juint(vals,"minconf");
locktime = juint(vals,"locktime");
satoshis = j64bits(vals,"amount");
txfee = j64bits(vals,"txfee");
if ( (rawtxtag= juint(vals,"rawtxtag")) == 0 )
OS_randombytes((uint8_t *)&rawtxtag,sizeof(rawtxtag));
if ( (rawtx= iguana_createrawtx(myinfo,rawtxtag,symbol,&vins,locktime,satoshis,spendscriptstr,changeaddr,txfee,minconf,addresses,juint(json,"timeout"))) != 0 )
{
//printf("return rawtx.(%s) remote.%p symbol.%s\n",rawtx,remoteaddr,symbol);
if ( remoteaddr != 0 && remoteaddr[0] != 0 && (coin= iguana_coinfind(symbol)) != 0 )
{
hexjson = cJSON_CreateObject();
jaddstr(hexjson,"rawtx",rawtx);
jaddstr(hexjson,"agent","iguana");
jaddstr(hexjson,"method","rawtx_result");
jaddnum(hexjson,"rawtxtag",rawtxtag);
if ( vins != 0 )
jadd(hexjson,"vins",vins);
valsobj = cJSON_CreateObject();
jaddstr(valsobj,"coin",symbol);
jadd(hexjson,"vals",valsobj);
retjson = iguana_requestjson(myinfo,hexjson);
}
else
{
jaddstr(retjson,"result",rawtx);
jadd(retjson,"vins",vins);
}
free(rawtx);
} else jaddstr(retjson,"error","couldnt create rawtx");
}
return(jprint(retjson,1));
}
//{"rawtx":"0100000011533957010252b9534fe0186625e3075606f9b547e223830af04b3fb9dab2aaadc7cad5300100000000ffffffff0280969800000000001976a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac700c023b000000001976a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac00000000","agent":"iguana","method":"rawtx_result","vins":[{"txid":"30d5cac7adaab2dab93f4bf00a8323e247b5f9065607e3256618e04f53b95202","vout":1,"scriptPubKey":"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac"}],"tag":"17812456603326673661"}
INT_ARRAY_STRING(iguana,rawtx_result,rawtxtag,vins,rawtx)
{
struct rawtx_queue *ptr = calloc(1,sizeof(*ptr) + strlen(rawtx) + 1);
//printf("rawtx_result\n");
strcpy(ptr->rawtx,rawtx);
if ( vins != 0 )
ptr->vins = jduplicate(vins);
ptr->rawtxtag = rawtxtag;
queue_enqueue("rawtxQ",&myinfo->rawtxQ,&ptr->DL,0);
return(0);
}
STRING_AND_INT(bitcoinrpc,sendrawtransaction,rawtx,allowhighfees) STRING_AND_INT(bitcoinrpc,sendrawtransaction,rawtx,allowhighfees)
{ {
cJSON *retjson = cJSON_CreateObject(); bits256 txid; cJSON *retjson = cJSON_CreateObject(); bits256 txid;
@ -1390,7 +1126,7 @@ S_D_SS(bitcoinrpc,sendtoaddress,address,amount,comment,comment2)
return(clonestr("{\"error\":\"need to unlock wallet\"}")); return(clonestr("{\"error\":\"need to unlock wallet\"}"));
myinfo->expiration++; myinfo->expiration++;
//iguana_unspentset(myinfo,coin); //iguana_unspentset(myinfo,coin);
return(sendtoaddress(myinfo,coin,address,amount * SATOSHIDEN,coin->txfee,comment,comment2,coin->minconfirms,0)); return(sendtoaddress(myinfo,coin,remoteaddr,address,amount * SATOSHIDEN,coin->txfee,comment,comment2,coin->minconfirms,0));
} }
SS_D_I_SS(bitcoinrpc,sendfrom,fromaccount,toaddress,amount,minconf,comment,comment2) SS_D_I_SS(bitcoinrpc,sendfrom,fromaccount,toaddress,amount,minconf,comment,comment2)
@ -1401,7 +1137,7 @@ SS_D_I_SS(bitcoinrpc,sendfrom,fromaccount,toaddress,amount,minconf,comment,comme
return(clonestr("{\"error\":\"need to unlock wallet\"}")); return(clonestr("{\"error\":\"need to unlock wallet\"}"));
myinfo->expiration++; myinfo->expiration++;
//iguana_unspentset(myinfo,coin); //iguana_unspentset(myinfo,coin);
return(sendtoaddress(myinfo,coin,toaddress,amount * SATOSHIDEN,coin->txfee,comment,comment2,minconf,fromaccount)); return(sendtoaddress(myinfo,coin,remoteaddr,toaddress,amount * SATOSHIDEN,coin->txfee,comment,comment2,minconf,fromaccount));
} }
S_A_I_S(bitcoinrpc,sendmany,fromaccount,payments,minconf,comment) S_A_I_S(bitcoinrpc,sendmany,fromaccount,payments,minconf,comment)
@ -1422,7 +1158,7 @@ S_A_I_S(bitcoinrpc,sendmany,fromaccount,payments,minconf,comment)
amount = jdouble(item,0); amount = jdouble(item,0);
val = amount * SATOSHIDEN; val = amount * SATOSHIDEN;
printf("(%s %.8f) ",coinaddr,dstr(val)); printf("(%s %.8f) ",coinaddr,dstr(val));
if ( (str= sendtoaddress(myinfo,coin,coinaddr,val,coin->txfee,comment,"",minconf,fromaccount)) != 0 ) if ( (str= sendtoaddress(myinfo,coin,remoteaddr,coinaddr,val,coin->txfee,comment,"",minconf,fromaccount)) != 0 )
{ {
free(str); free(str);
} }

2
iguana/iguana_peers.c

@ -1042,7 +1042,7 @@ int32_t iguana_peerslotinit(struct iguana_info *coin,struct iguana_peer *addr,in
printf("cant create.(%s)\n",fname); printf("cant create.(%s)\n",fname);
return(-1); return(-1);
} }
if ( coin->VALIDATENODE != 0 || coin->RELAYNODE != 0 ) if ( coin->MAXPEERS == 1 || coin->VALIDATENODE != 0 || coin->RELAYNODE != 0 )
{ {
iguana_vinsfname(coin,0,fname,addr->addrind); iguana_vinsfname(coin,0,fname,addr->addrind);
if ( (addr->vinsfp= fopen(fname,"rb+")) != 0 ) if ( (addr->vinsfp= fopen(fname,"rb+")) != 0 )

4
iguana/iguana_rpc.c

@ -1029,8 +1029,10 @@ void iguana_rpcloop(void *args)
else myinfo->argport = 0; else myinfo->argport = 0;
if ( jsonbuf == 0 ) if ( jsonbuf == 0 )
jsonbuf = calloc(1,IGUANA_MAXPACKETSIZE); jsonbuf = calloc(1,IGUANA_MAXPACKETSIZE);
while ( (bindsock= iguana_socket(1,"127.0.0.1",port)) < 0 ) if ( (bindsock= iguana_socket(1,"127.0.0.1",port)) < 0 )
{ {
//if ( coin->MAXPEERS == 1 )
// break;
//exit(-1); //exit(-1);
sleep(3); sleep(3);
} }

91
iguana/iguana_sign.c

@ -101,7 +101,7 @@ int32_t iguana_voutparse(int32_t rwflag,uint8_t *serialized,struct iguana_msgvou
return(len); return(len);
} }
cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin) cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin,bits256 sigtxid)
{ {
char str[65]; int32_t vout; cJSON *json = cJSON_CreateObject(); char str[65]; int32_t vout; cJSON *json = cJSON_CreateObject();
vout = vin->prev_vout; vout = vin->prev_vout;
@ -112,6 +112,8 @@ cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin)
{ {
jaddstr(json,"txid",bits256_str(str,vin->prev_hash)); jaddstr(json,"txid",bits256_str(str,vin->prev_hash));
jaddnum(json,"vout",vout); jaddnum(json,"vout",vout);
if ( bits256_nonz(sigtxid) != 0 )
jaddbits256(json,"sigtxid",sigtxid);
if ( vin->scriptlen > 0 ) if ( vin->scriptlen > 0 )
iguana_addscript(coin,json,vin->vinscript,vin->scriptlen,"scriptSig"); iguana_addscript(coin,json,vin->vinscript,vin->scriptlen,"scriptSig");
if ( vin->spendlen > 0 ) if ( vin->spendlen > 0 )
@ -293,14 +295,52 @@ cJSON *iguana_voutjson(struct iguana_info *coin,struct iguana_msgvout *vout,int3
return(json); return(json);
} }
bits256 bitcoin_sigtxid(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,int32_t vini,uint8_t *spendscript,int32_t spendlen,int32_t hashtype,char *vpnstr)
{
int32_t i,len; bits256 sigtxid,txid,revsigtxid; struct iguana_msgtx dest;
dest = *msgtx;
memset(sigtxid.bytes,0,sizeof(sigtxid));
if ( hashtype != SIGHASH_ALL )
{
printf("currently only SIGHASH_ALL supported, not %d\n",hashtype);
return(sigtxid);
}
for (i=0; i<msgtx->tx_in; i++)
{
if ( i == vini )
{
dest.vins[i].vinscript = spendscript;
dest.vins[i].scriptlen = spendlen;
}
else
{
dest.vins[i].vinscript = (uint8_t *)"";
dest.vins[i].scriptlen = 0;
}
dest.vins[i].p2shlen = 0;
dest.vins[i].redeemscript = 0;
}
len = iguana_rwmsgtx(coin,1,0,serialized,maxlen,&dest,&txid,vpnstr,0,0);
if ( len > 0 )
{
len += iguana_rwnum(1,&serialized[len],sizeof(hashtype),&hashtype);
revsigtxid = bits256_doublesha256(0,serialized,len);
for (i=0; i<sizeof(revsigtxid); i++)
sigtxid.bytes[31-i] = revsigtxid.bytes[i];
}
return(sigtxid);
}
int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen) int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen)
{ {
int32_t i,n,len = 0,extraused=0; uint8_t *txstart = serialized; char txidstr[65]; cJSON *array=0; int32_t i,n,len = 0,extraused=0; uint8_t *txstart = serialized,*sigser=0; char txidstr[65]; cJSON *array=0; bits256 sigtxid;
len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version);
if ( json != 0 ) if ( json != 0 )
{ {
jaddnum(json,"version",msg->version); jaddnum(json,"version",msg->version);
array = cJSON_CreateArray(); array = cJSON_CreateArray();
if ( rwflag == 0 )
sigser = calloc(1,maxsize);
} }
//printf("version.%d\n",msg->version); //printf("version.%d\n",msg->version);
if ( coin->chain->hastimestamp != 0 ) if ( coin->chain->hastimestamp != 0 )
@ -340,10 +380,17 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t rwflag,cJSON *json,uint8
return(-1); return(-1);
} }
if ( array != 0 ) if ( array != 0 )
jaddi(array,iguana_vinjson(coin,&msg->vins[i])); {
if ( sigser != 0 )
sigtxid = bitcoin_sigtxid(coin,sigser,maxsize,msg,i,msg->vins[i].spendscript,msg->vins[i].spendlen,SIGHASH_ALL,vpnstr);
else memset(sigtxid.bytes,0,sizeof(sigtxid));
jaddi(array,iguana_vinjson(coin,&msg->vins[i],sigtxid));
}
} }
if ( array != 0 ) if ( array != 0 )
{ {
if ( sigser != 0 )
free(sigser);
jadd(json,"vin",array); jadd(json,"vin",array);
jaddnum(json,"numvins",msg->tx_in); jaddnum(json,"numvins",msg->tx_in);
array = cJSON_CreateArray(); array = cJSON_CreateArray();
@ -511,6 +558,8 @@ char *bitcoin_json2hex(struct supernet_info *myinfo,struct iguana_info *coin,bit
cJSON *bitcoin_hex2json(struct iguana_info *coin,bits256 *txidp,struct iguana_msgtx *msgtx,char *txbytes,uint8_t *extraspace,int32_t extralen) cJSON *bitcoin_hex2json(struct iguana_info *coin,bits256 *txidp,struct iguana_msgtx *msgtx,char *txbytes,uint8_t *extraspace,int32_t extralen)
{ {
int32_t n,len; char vpnstr[64]; struct iguana_msgtx M; uint8_t *serialized; cJSON *txobj; int32_t n,len; char vpnstr[64]; struct iguana_msgtx M; uint8_t *serialized; cJSON *txobj;
if ( coin == 0 )
return(0);
txobj = cJSON_CreateObject(); txobj = cJSON_CreateObject();
if ( msgtx == 0 ) if ( msgtx == 0 )
msgtx = &M; msgtx = &M;
@ -531,42 +580,6 @@ cJSON *bitcoin_hex2json(struct iguana_info *coin,bits256 *txidp,struct iguana_ms
return(txobj); return(txobj);
} }
bits256 bitcoin_sigtxid(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,int32_t vini,uint8_t *spendscript,int32_t spendlen,int32_t hashtype,char *vpnstr)
{
int32_t i,len; bits256 sigtxid,txid,revsigtxid; struct iguana_msgtx dest;
dest = *msgtx;
memset(sigtxid.bytes,0,sizeof(sigtxid));
if ( hashtype != SIGHASH_ALL )
{
printf("currently only SIGHASH_ALL supported, not %d\n",hashtype);
return(sigtxid);
}
for (i=0; i<msgtx->tx_in; i++)
{
if ( i == vini )
{
dest.vins[i].vinscript = spendscript;
dest.vins[i].scriptlen = spendlen;
}
else
{
dest.vins[i].vinscript = (uint8_t *)"";
dest.vins[i].scriptlen = 0;
}
dest.vins[i].p2shlen = 0;
dest.vins[i].redeemscript = 0;
}
len = iguana_rwmsgtx(coin,1,0,serialized,maxlen,&dest,&txid,vpnstr,0,0);
if ( len > 0 )
{
len += iguana_rwnum(1,&serialized[len],sizeof(hashtype),&hashtype);
revsigtxid = bits256_doublesha256(0,serialized,len);
for (i=0; i<sizeof(revsigtxid); i++)
sigtxid.bytes[31-i] = revsigtxid.bytes[i];
}
return(sigtxid);
}
int32_t iguana_msgtx_Vset(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,struct vin_info *V) int32_t iguana_msgtx_Vset(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,struct vin_info *V)
{ {
int32_t vini,j,scriptlen,p2shlen,siglen,plen,len = 0; uint8_t *script; struct vin_info *vp; int32_t vini,j,scriptlen,p2shlen,siglen,plen,len = 0; uint8_t *script; struct vin_info *vp;

2
iguana/iguana_spendvectors.c

@ -1043,7 +1043,7 @@ int32_t iguana_bundlevalidate(struct iguana_info *coin,struct iguana_bundle *bp,
static int32_t totalerrs,totalvalidated; static int32_t totalerrs,totalvalidated;
FILE *fp; char fname[1024]; uint8_t *blockspace; uint32_t now = (uint32_t)time(NULL); FILE *fp; char fname[1024]; uint8_t *blockspace; uint32_t now = (uint32_t)time(NULL);
int32_t i,max,len,errs = 0; struct sha256_vstate vstate; bits256 validatehash; int64_t total = 0; int32_t i,max,len,errs = 0; struct sha256_vstate vstate; bits256 validatehash; int64_t total = 0;
if ( (coin->VALIDATENODE == 0 && coin->RELAYNODE == 0) || bp->ramchain.from_ro != 0 || bp == coin->current ) if ( (coin->MAXPEERS > 1 && coin->VALIDATENODE == 0 && coin->RELAYNODE == 0) || bp->ramchain.from_ro != 0 || bp == coin->current )
{ {
bp->validated = (uint32_t)time(NULL); bp->validated = (uint32_t)time(NULL);
return(bp->n); return(bp->n);

8
iguana/m_LP

@ -0,0 +1,8 @@
#./configure --enable-endomorphism --enable-module-ecdh --enable-module-schnorr --enable-module-rangeproof --enable-experimental --enable-module_recovery
rm ../agents/iguana *.o
git pull
cd secp256k1; ./m_unix; cd ..
gcc -g -Wno-deprecated -c -O2 *.c #databases/iguana_DB.c
gcc -g -Wno-deprecated -c main.c iguana777.c iguana_bundles.c
#gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lcrypto -lpthread -lm #../includes/libsecp256k1.a -lgmp
gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lcurl -lssl -lcrypto -lpthread -lz -lm

1
iguana/m_LTC

@ -0,0 +1 @@
../agents/iguana "{\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"LTC\",\"active\":1,\"maxpeers\":1,\"services\":128,\"poll\":30,\"RELAY\":0,\"VALIDATE\":0}"

2
iguana/m_unix

@ -4,5 +4,5 @@ git pull
cd secp256k1; ./m_unix; cd .. cd secp256k1; ./m_unix; cd ..
gcc -g -Wno-deprecated -c -O2 *.c #databases/iguana_DB.c gcc -g -Wno-deprecated -c -O2 *.c #databases/iguana_DB.c
gcc -g -Wno-deprecated -c main.c iguana777.c iguana_bundles.c gcc -g -Wno-deprecated -c main.c iguana777.c iguana_bundles.c
#gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lcurl -lssl -lcrypto -lpthread -lm #../includes/libsecp256k1.a -lgmp #gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lcrypto -lpthread -lm #../includes/libsecp256k1.a -lgmp
gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lpthread -lm gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lpthread -lm

4
iguana/main.c

@ -1164,10 +1164,10 @@ void iguana_appletests(struct supernet_info *myinfo)
//int32_t iguana_schnorr_test(void *ctx); //int32_t iguana_schnorr_test(void *ctx);
//iguana_schnorr_test(myinfo->ctx); getchar(); //iguana_schnorr_test(myinfo->ctx); getchar();
if ( 1 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":64,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"poll\":100}"),0,myinfo->rpcport)) != 0 ) if ( 1 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":128,\"maxpeers\":1,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"poll\":100}"),0,myinfo->rpcport)) != 0 )
{ {
free(str); free(str);
if ( 1 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":64,\"newcoin\":\"BTC\",\"active\":0,\"numhelpers\":4,\"poll\":100}"),0,myinfo->rpcport)) != 0 ) if ( 0 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":64,\"newcoin\":\"BTC\",\"active\":0,\"numhelpers\":4,\"poll\":100}"),0,myinfo->rpcport)) != 0 )
{ {
free(str); free(str);
if ( 0 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"agent\":\"SuperNET\",\"method\":\"login\",\"handle\":\"alice\",\"password\":\"alice\",\"passphrase\":\"alice\"}"),0,myinfo->rpcport)) != 0 ) if ( 0 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"agent\":\"SuperNET\",\"method\":\"login\",\"handle\":\"alice\",\"password\":\"alice\",\"passphrase\":\"alice\"}"),0,myinfo->rpcport)) != 0 )

20
iguana/swaps/iguana_BTCswap.c

@ -14,6 +14,7 @@
******************************************************************************/ ******************************************************************************/
#include "../exchanges/bitcoin.h" #include "../exchanges/bitcoin.h"
#include "../../basilisk/basilisk.h"
/* https://bitcointalk.org/index.php?topic=1340621.msg13828271#msg13828271 /* https://bitcointalk.org/index.php?topic=1340621.msg13828271#msg13828271
https://bitcointalk.org/index.php?topic=1364951 https://bitcointalk.org/index.php?topic=1364951
Tier Nolan's approach is followed with the following changes: Tier Nolan's approach is followed with the following changes:
@ -169,7 +170,7 @@ void iguana_addinputs(struct iguana_info *coin,struct bitcoin_spend *spend,cJSON
struct bitcoin_statetx *instantdex_signtx(char *str,struct supernet_info *myinfo,struct iguana_info *coin,uint32_t locktime,char *scriptstr,int64_t satoshis,int64_t txfee,int32_t minconf,int32_t myside) struct bitcoin_statetx *instantdex_signtx(char *str,struct supernet_info *myinfo,struct iguana_info *coin,uint32_t locktime,char *scriptstr,int64_t satoshis,int64_t txfee,int32_t minconf,int32_t myside)
{ {
struct iguana_waddress *waddr; struct iguana_waccount *wacct; struct bitcoin_statetx *tx=0; uint8_t pubkey33[33]; char coinaddr[64],wifstr[64]; char *rawtx,*signedtx,*retstr; bits256 signedtxid; uint32_t rawtxtag; int32_t flag,completed; cJSON *valsobj,*vins,*retjson=0,*privkey,*argjson,*addresses; struct iguana_waddress *waddr; struct iguana_waccount *wacct; struct bitcoin_statetx *tx=0; uint8_t pubkey33[33]; char coinaddr[64],wifstr[64]; char *rawtx,*signedtx,*retstr; bits256 signedtxid; uint32_t basilisktag; int32_t flag,completed; cJSON *valsobj,*vins,*retjson=0,*privkey,*argjson,*addresses;
if ( (waddr= iguana_getaccountaddress(myinfo,coin,0,0,coin->changeaddr,"change")) == 0 ) if ( (waddr= iguana_getaccountaddress(myinfo,coin,0,0,coin->changeaddr,"change")) == 0 )
{ {
printf("no change addr error\n"); printf("no change addr error\n");
@ -193,12 +194,12 @@ struct bitcoin_statetx *instantdex_signtx(char *str,struct supernet_info *myinfo
jadd64bits(valsobj,"amount",satoshis); jadd64bits(valsobj,"amount",satoshis);
jadd64bits(valsobj,"txfee",txfee); jadd64bits(valsobj,"txfee",txfee);
jaddnum(valsobj,"minconf",minconf); jaddnum(valsobj,"minconf",minconf);
rawtxtag = (uint32_t)rand(); basilisktag = (uint32_t)rand();
jaddnum(valsobj,"rawtxtag",rawtxtag); jaddnum(valsobj,"basilisktag",basilisktag);
jaddnum(valsobj,"locktime",locktime); jaddnum(valsobj,"locktime",locktime);
argjson = cJSON_CreateObject(); argjson = cJSON_CreateObject();
jaddnum(argjson,"timeout",60000); jaddnum(argjson,"timeout",30000);
if ( (retstr= iguana_rawtx(myinfo,coin,argjson,0,coin->changeaddr,addresses,valsobj,scriptstr)) != 0 ) if ( (retstr= basilisk_rawtx(myinfo,coin,argjson,0,coin->changeaddr,addresses,valsobj,scriptstr)) != 0 )
{ {
printf("%s got.(%s)\n",str,retstr); printf("%s got.(%s)\n",str,retstr);
flag = 0; flag = 0;
@ -207,15 +208,6 @@ struct bitcoin_statetx *instantdex_signtx(char *str,struct supernet_info *myinfo
if ( (rawtx= jstr(retjson,"result")) != 0 && (vins= jobj(retjson,"vins")) != 0 ) if ( (rawtx= jstr(retjson,"result")) != 0 && (vins= jobj(retjson,"vins")) != 0 )
flag = 1; flag = 1;
} }
if ( flag == 0 )
{
vins = 0;
if ( (rawtx= iguana_pollrawtx(&myinfo->rawtxQ,&vins,rawtxtag,OS_milliseconds() + 60000)) != 0 )
{
if ( vins != 0 )
flag = 2;
}
}
if ( flag != 0 && vins != 0 ) if ( flag != 0 && vins != 0 )
{ {
//printf("vins.(%s)\n",jprint(vins,0)); //printf("vins.(%s)\n",jprint(vins,0));

2
iguana/tests/balances

@ -1 +1 @@
curl --url "http://127.0.0.1:7778" --data "{\"timeout\":20000,\"agent\":\"iguana\",\"method\":\"balances\",\"lastheight\":0,\"activecoin\":\"BTCD\",\"addresses\":[\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\"]}" curl --url "http://127.0.0.1:7778" --data "{\"timeout\":20000,\"agent\":\"basilisk\",\"method\":\"balances\",\"lastheight\":0,\"activecoin\":\"BTCD\",\"addresses\":[\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\"]}"

2
iguana/tests/rawtx

@ -1 +1 @@
curl --url "http://127.0.0.1:14632" --data "{\"timeout\":25000,\"agent\":\"iguana\",\"method\":\"rawtx\",\"changeaddr\":\"1Hgzt5xsnbfc8UTWqWKSTLRm5bEYHYBoCE\",\"addresses\":[\"1Hgzt5xsnbfc8UTWqWKSTLRm5bEYHYBoCE\"],\"vals\":{\"coin\":\"BTC\",\"amount\":\"20000\"},\"spendscriptstr\":\"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac\"}" curl --url "http://127.0.0.1:14632" --data "{\"timeout\":25000,\"agent\":\"basilisk\",\"method\":\"rawtx\",\"changeaddr\":\"1Hgzt5xsnbfc8UTWqWKSTLRm5bEYHYBoCE\",\"addresses\":[\"1Hgzt5xsnbfc8UTWqWKSTLRm5bEYHYBoCE\"],\"vals\":{\"coin\":\"BTC\",\"amount\":\"20000\"},\"spendscriptstr\":\"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac\"}"

1
iguana/tests/rawtxB

@ -0,0 +1 @@
curl --url "http://127.0.0.1:7778" --data "{\"timeout\":25000,\"agent\":\"basilisk\",\"method\":\"rawtx\",\"changeaddr\":\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\",\"addresses\":[\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\"],\"vals\":{\"coin\":\"BTCD\",\"amount\":\"20000\"},\"spendscriptstr\":\"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac\"}"

8
includes/iguana_apideclares.h

@ -14,6 +14,10 @@
******************************************************************************/ ******************************************************************************/
INT_ARRAY_STRING(basilisk,balances,lastheight,addresses,activecoin);
STRING_ARRAY_OBJ_STRING(basilisk,rawtx,changeaddr,addresses,vals,spendscriptstr);
INT_ARRAY_STRING(basilisk,result,basilisktag,argjson,hexmsg);
ZERO_ARGS(bitcoinrpc,getinfo); ZERO_ARGS(bitcoinrpc,getinfo);
ZERO_ARGS(bitcoinrpc,getblockcount); ZERO_ARGS(bitcoinrpc,getblockcount);
ZERO_ARGS(bitcoinrpc,getbestblockhash); ZERO_ARGS(bitcoinrpc,getbestblockhash);
@ -83,10 +87,6 @@ ZERO_ARGS(bitcoinrpc,gettxoutsetinfo);
ZERO_ARGS(bitcoinrpc,getrawchangeaddress); ZERO_ARGS(bitcoinrpc,getrawchangeaddress);
SS_D_I_S(bitcoinrpc,move,fromaccount,toaccount,amount,minconf,comment); SS_D_I_S(bitcoinrpc,move,fromaccount,toaccount,amount,minconf,comment);
INT_ARRAY_STRING(iguana,balances,lastheight,addresses,activecoin);
STRING_ARRAY_OBJ_STRING(iguana,rawtx,changeaddr,addresses,vals,spendscriptstr);
INT_ARRAY_STRING(iguana,rawtx_result,rawtxtag,vins,rawtx);
STRING_ARG(iguana,initfastfind,activecoin); STRING_ARG(iguana,initfastfind,activecoin);
STRING_ARG(iguana,peers,activecoin); STRING_ARG(iguana,peers,activecoin);
STRING_AND_INT(iguana,maxpeers,activecoin,max); STRING_AND_INT(iguana,maxpeers,activecoin,max);

Loading…
Cancel
Save