Browse Source

tools/common.mk

release/v0.1
jl777 9 years ago
parent
commit
4d06e8c579
  1. 3
      crypto777/Makefile
  2. 101
      deprecated/obsolete.h
  3. 7
      iguana/Makefile
  4. 20
      iguana/SuperNET.h
  5. 648
      iguana/exchanges/bitcoin.c
  6. 1
      iguana/exchanges/bitcoin.h
  7. 180
      iguana/exchanges/nxtae.c
  8. 12
      iguana/iguana777.h
  9. 196
      iguana/iguana_instantdex.c
  10. 4
      iguana/iguana_json.c
  11. 5
      iguana/iguana_pubkeys.c
  12. 2
      iguana/iguana_tx.c
  13. 2
      iguana/main.c
  14. 6
      includes/iguana_apideclares.h
  15. 2
      includes/iguana_apidefs.h
  16. 1
      includes/iguana_apiundefs.h

3
crypto777/Makefile

@ -13,7 +13,8 @@ TARGET = crypto777
EXTRA= -D__PNACL -O2
include $(NACL_SDK_ROOT)/tools/common.mk
#include $(NACL_SDK_ROOT)/tools/common.mk
include tools/common.mk
CHROME_ARGS += --allow-nacl-socket-api=127.0.0.1
DEPS = nacl_io

101
deprecated/obsolete.h

@ -13092,4 +13092,105 @@ len = 0;
return(clonestr("{\"error\":\"need pubkey\"}"));
}*/
int32_t bitcoin_outputscript(struct iguana_info *coin,char *pubkeys[],int32_t *scriptlenp,uint8_t *scriptspace,bits256 txid,int32_t vout)
{
struct iguana_txid T,*tx; int32_t height,numpubs = 1; char asmstr[8192]; struct iguana_msgvout v;
if ( 0 )
{
*scriptlenp = 0;
if ( (tx= iguana_txidfind(coin,&height,&T,txid)) != 0 )
{
*scriptlenp = iguana_voutset(coin,scriptspace,asmstr,height,&v,tx,vout);
return(numpubs);
}
}
//char *str = "2103506a52e95cdfbb9d17d702af6259ba7de8b7a604007999e0266edbf6e4bb6974ac";
char *str = "76a914010966776006953d5567439e5e39f86a0d273bee88ac";
*scriptlenp = (int32_t)strlen(str) >> 1;
decode_hex(scriptspace,*scriptlenp,str);
//pubkeys[0] = clonestr("03506a52e95cdfbb9d17d702af6259ba7de8b7a604007999e0266edbf6e4bb6974");
pubkeys[0] = clonestr("0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6");
return(numpubs);
}
cJSON *bitcoin_txjson(struct iguana_info *coin,struct iguana_msgtx *msgtx,struct vin_info *V)
{
char vpnstr[2]; int32_t n; uint8_t *serialized; bits256 txid; cJSON *json = cJSON_CreateObject();
vpnstr[0] = 0;
serialized = malloc(IGUANA_MAXPACKETSIZE);
if ( (n= iguana_rwmsgtx(coin,1,json,serialized,IGUANA_MAXPACKETSIZE,msgtx,&txid,vpnstr,V)) < 0 )
{
printf("bitcoin_txtest: n.%d\n",n);
}
free(serialized);
return(json);
}
/*{
for (i=0; i<T->numinputs; i++)
strcpy(T->inputs[i].sigs,"00");
strcpy(vin->sigs,redeemscript);
vin->sequence = (uint32_t)-1;
T->nlocktime = 0;
//disp_cointx(&T);
emit_cointx(&hash2,data,sizeof(data),T,oldtx_format,SIGHASH_ALL);
//printf("HASH2.(%llx)\n",(long long)hash2.txid);
if ( bp_sign(&key,hash2.bytes,sizeof(hash2),&sig,&siglen) != 0 )
{
memcpy(sigbuf,sig,siglen);
sigbuf[siglen++] = SIGHASH_ALL;
init_hexbytes_noT(sigs[privkeyind],sigbuf,(int32_t)siglen);
strcpy(vin->sigs,"00");
for (i=0; i<n; i++)
{
if ( sigs[i][0] != 0 )
{
sprintf(vin->sigs + strlen(vin->sigs),"%02x%s",(int32_t)strlen(sigs[i])>>1,sigs[i]);
//printf("(%s).%ld ",sigs[i],strlen(sigs[i]));
}
}
len = (int32_t)(strlen(redeemscript)/2);
if ( len >= 0xfd )
sprintf(&vin->sigs[strlen(vin->sigs)],"4d%02x%02x",len & 0xff,(len >> 8) & 0xff);
else sprintf(&vin->sigs[strlen(vin->sigs)],"4c%02x",len);
sprintf(&vin->sigs[strlen(vin->sigs)],"%s",redeemscript);
//printf("after A.(%s) othersig.(%s) siglen.%02lx -> (%s)\n",hexstr,othersig != 0 ? othersig : "",siglen,vin->sigs);
//printf("vinsigs.(%s) %ld\n",vin->sigs,strlen(vin->sigs));
_emit_cointx(hexstr,sizeof(hexstr),T,oldtx_format);
//disp_cointx(&T);
free(T);
return(clonestr(hexstr));
}
else printf("error signing\n");
free(T);
}*/
/*cJSON *iguana_txjson(struct iguana_info *coin,struct iguana_txid *tx,int32_t height,struct vin_info *V)
{
struct iguana_msgvin vin; struct iguana_msgvout vout; int32_t i; char asmstr[512],str[65]; uint8_t space[8192];
cJSON *vouts,*vins,*json;
json = cJSON_CreateObject();
jaddstr(json,"txid",bits256_str(str,tx->txid));
if ( height >= 0 )
jaddnum(json,"height",height);
jaddnum(json,"version",tx->version);
jaddnum(json,"timestamp",tx->timestamp);
jaddnum(json,"locktime",tx->locktime);
vins = cJSON_CreateArray();
vouts = cJSON_CreateArray();
for (i=0; i<tx->numvouts; i++)
{
iguana_voutset(coin,space,asmstr,height,&vout,tx,i);
jaddi(vouts,iguana_voutjson(coin,&vout,i,tx->txid));
}
jadd(json,"vout",vouts);
for (i=0; i<tx->numvins; i++)
{
iguana_vinset(coin,height,&vin,tx,i);
jaddi(vins,iguana_vinjson(coin,&vin,V != 0 ? &V[i] : 0));
}
jadd(json,"vin",vins);
return(json);
}*/
#endif

7
iguana/Makefile

@ -13,7 +13,8 @@ TARGET = iguana
EXTRA= -D__PNACL -DNN_DISABLE_GETADDRINFO_A=1 -DNN_USE_LITERAL_IFADDR=1 -DNN_HAVE_STDINT=1 -DNN_HAVE_MSG_CONTROL=0 -DNN_HAVE_SEMAPHORE=1 -DNN_HAVE_POLL=1 -DNN_HAVE_SOCKETPAIR=1 -DNN_USE_POLL=1
include $(NACL_SDK_ROOT)/tools/common.mk
#include $(NACL_SDK_ROOT)/tools/common.mk
include tools/common.mk
include iguana.sources
include ../crypto777/crypto777.sources
@ -21,7 +22,9 @@ CHROME_ARGS += --allow-nacl-socket-api=127.0.0.1
DEPS = nacl_io
#LIBS = curl ssl crypto z glibc-compat nacl_spawn ppapi nacl_io ppapi_cpp ppapi_simple # cli_main
LIBS = crypto777 curl ssl crypto z pthread ppapi nacl_io
#LIBS = crypto777 curl ssl crypto z pthread ppapi nacl_io
#DEPS = nacl_io
LIBS = crypto777 curl ssl crypto z glibc-compat nacl_spawn ppapi nacl_io ppapi_simple # cli_main ppapi_cpp ppapi_simple
CFLAGS = -Wall -O2 -fno-strict-aliasing $(EXTRA)
LFLAGS = libs

20
iguana/SuperNET.h

@ -84,10 +84,27 @@ struct supernet_info
int32_t LBsock,PUBsock,reqsock,subsock,networktimeout,maxdelay;
uint16_t LBport,PUBport,reqport,subport;
struct nn_pollfd pfd[SUPERNET_MAXAGENTS]; //struct relay_info active;
struct supernet_agent agents[SUPERNET_MAXAGENTS]; queue_t acceptQ; int32_t numagents,numexchanges;
struct supernet_agent agents[SUPERNET_MAXAGENTS]; queue_t acceptQ,acceptableQ;
int32_t numagents,numexchanges;
struct exchange_info *tradingexchanges[SUPERNET_MAXEXCHANGES];
char handle[1024];
};
#define NXT_ASSETID ('N' + ((uint64_t)'X'<<8) + ((uint64_t)'T'<<16)) // 5527630
#define INSTANTDEX_ACCT "4383817337783094122"
union _NXT_tx_num { int64_t amountNQT; int64_t quantityQNT; };
struct NXT_tx
{
bits256 refhash,sighash,fullhash;
uint64_t senderbits,recipientbits,assetidbits,txid,priceNQT,quoteid;
int64_t feeNQT;
union _NXT_tx_num U;
int32_t deadline,type,subtype,verify,number;
uint32_t timestamp;
char comment[4096];
};
uint64_t set_NXTtx(struct supernet_info *myinfo,struct NXT_tx *tx,uint64_t assetidbits,int64_t amount,uint64_t other64bits,int32_t feebits);
cJSON *gen_NXT_tx_json(struct supernet_info *myinfo,char *fullhash,struct NXT_tx *utx,char *reftxid,double myshare);
int32_t calc_raw_NXTtx(struct supernet_info *myinfo,char *fullhash,char *utxbytes,char *sighash,uint64_t assetidbits,int64_t amount,uint64_t other64bits);
/*struct supernet_endpoint
{
@ -166,6 +183,7 @@ double instantdex_aveprice(struct supernet_info *myinfo,struct exchange_quote *s
void SuperNET_setkeys(struct supernet_info *myinfo,void *pass,int32_t passlen,int32_t dosha256);
char *InstantDEX_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *remoteaddr);
double instantdex_acceptable(struct supernet_info *myinfo,cJSON *array,char *refstr,char *base,char *rel,double volume);
#endif

648
iguana/exchanges/bitcoin.c

@ -31,6 +31,15 @@ static const char base58_chars[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijk
#define IGUANA_SCRIPT_DATA 11
#define IGUANA_SCRIPT_STRANGE 15
int32_t bitcoin_pubkeylen(const uint8_t *pubkey)
{
if ( pubkey[0] == 2 || pubkey[0] == 3 )
return(33);
else if ( pubkey[0] == 4 )
return(65);
else return(-1);
}
void bn_mpi2bn(BIGNUM *vo,uint8_t *data,int32_t datalen)
{
uint8_t vch2[64 + 4]; uint32_t i,vch2_len = (int32_t)datalen + 4;
@ -137,7 +146,8 @@ int32_t bitcoin_base58decode(uint8_t *data,char *coinaddr)
be_sz = (uint32_t)len + (uint32_t)zeroes;
memset(data,0,be_sz);
for (i=0; i<len; i++)
data[i + zeroes] = revdata[be_sz - 1 - i];
data[i+zeroes] = revdata[len - 1 - i];
//printf("len.%d be_sz.%d zeroes.%d data[0] %02x\n",len,be_sz,zeroes,data[0]);
out:
BN_clear_free(&bn58), BN_clear_free(&bn), BN_clear_free(&bnChar);
BN_CTX_free(ctx);
@ -146,23 +156,29 @@ out:
int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr)
{
bits256 hash; uint8_t buf[25]; int32_t len;
bits256 hash; uint8_t *buf,_buf[25]; int32_t len;
memset(rmd160,0,20);
*addrtypep = 0;
buf = _buf;
if ( (len= bitcoin_base58decode(buf,coinaddr)) >= 4 )
{
// validate with trailing hash, then remove hash
hash = bits256_doublesha256(0,buf,len - 4);
*addrtypep = *buf;
memcpy(rmd160,buf+1,20);
if ( (buf[len - 4]&0xff) == hash.bytes[31] && (buf[len - 3]&0xff) == hash.bytes[30] &&(buf[len - 2]&0xff) == hash.bytes[29] &&(buf[len - 1]&0xff) == hash.bytes[28] )
{
*addrtypep = buf[0];
memcpy(rmd160,buf+1,20);
return(20);
//printf("coinaddr.(%s) valid checksum\n",coinaddr);
}
else
{
char str[65]; printf("checkhash mismatch %02x %02x %02x %02x vs %02x %02x %02x %02x (%s)\n",buf[len - 4]&0xff,buf[len - 3]&0xff,buf[len - 2]&0xff,buf[len - 1]&0xff,hash.bytes[31],hash.bytes[30],hash.bytes[29],hash.bytes[28],bits256_str(str,hash));
int32_t i; char hexaddr[64];
btc_convaddr(hexaddr,coinaddr);
for (i=0; i<len; i++)
printf("%02x ",buf[i]);
char str[65]; printf("\nhex.(%s) checkhash.(%s) len.%d mismatch %02x %02x %02x %02x vs %02x %02x %02x %02x (%s)\n",hexaddr,coinaddr,len,buf[len - 4]&0xff,buf[len - 3]&0xff,buf[len - 2]&0xff,buf[len - 1]&0xff,hash.bytes[31],hash.bytes[30],hash.bytes[29],hash.bytes[28],bits256_str(str,hash));
}
return(20);
}
return(0);
}
@ -170,12 +186,15 @@ int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr
char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey,int32_t len)
{
int32_t i; uint8_t data[25]; bits256 hash; char checkaddr[65];
vcalc_sha256(0,hash.bytes,pubkey,len);
calc_rmd160(0,data+1,hash.bytes,sizeof(hash));
if ( len != 20 )
{
vcalc_sha256(0,hash.bytes,pubkey,len);
calc_rmd160(0,data+1,hash.bytes,sizeof(hash));
} else memcpy(data+1,pubkey,20);
btc_convrmd160(checkaddr,addrtype,data+1);
for (i=0; i<20; i++)
printf("%02x",data[i+1]);
printf(" RMD160 len.%d\n",len);
//for (i=0; i<20; i++)
// printf("%02x",data[i+1]);
//printf(" RMD160 len.%d\n",len);
data[0] = addrtype;
hash = bits256_doublesha256(0,data,21);
for (i=0; i<4; i++)
@ -184,7 +203,8 @@ char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey,int32_t le
{
uint8_t checktype,rmd160[20];
bitcoin_addr2rmd160(&checktype,rmd160,coinaddr);
printf("checkaddr.(%s) vs coinaddr.(%s) %02x vs [%02x] memcmp.%d\n",checkaddr,coinaddr,addrtype,checktype,memcmp(rmd160,data+1,20));
if ( strcmp(checkaddr,coinaddr) != 0 )
printf("checkaddr.(%s) vs coinaddr.(%s) %02x vs [%02x] memcmp.%d\n",checkaddr,coinaddr,addrtype,checktype,memcmp(rmd160,data+1,20));
}
return(coinaddr);
}
@ -288,7 +308,10 @@ int32_t bitcoin_verify(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen
int32_t bitcoin_pubkeyspend(uint8_t *script,int32_t n,uint8_t pubkey[66])
{
script[n++] = pubkey[0]; memcpy(&script[n],pubkey,pubkey[0]+1); n += pubkey[0]+1;
int32_t scriptlen = bitcoin_pubkeylen(pubkey);
script[n++] = scriptlen;
memcpy(&script[n],pubkey,scriptlen);
n += scriptlen;
script[n++] = SCRIPT_OP_CHECKSIG;
return(n);
}
@ -319,54 +342,84 @@ int32_t bitcoin_checklocktimeverify(uint8_t *script,int32_t n,uint32_t locktime)
return(n);
}
int32_t bitcoin_pubkeylen(uint8_t *pubkey)
{
if ( pubkey[0] == 2 || pubkey[0] == 3 )
return(33);
else if ( pubkey[0] == 4 )
return(65);
else return(-1);
}
int32_t bitcoin_MofN(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,struct vin_info *vp,int32_t M,int32_t N)
int32_t bitcoin_MofNspendscript(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,const struct vin_info *vp)
{
uint8_t sha256[32]; int32_t i,plen;
script[n++] = 0x50 + M;
for (i=0; i<N; i++)
script[n++] = 0x50 + vp->M;
for (i=0; i<vp->N; i++)
{
if ( (plen= bitcoin_pubkeylen(vp->signers[i].pubkey)) < 0 )
return(-1);
memcpy(&script[n],vp->signers[i].pubkey,plen);
n += plen;
}
script[n++] = 0x50 + N;
script[n++] = 0x50 + vp->N;
script[n++] = SCRIPT_OP_CHECKMULTISIG;
vcalc_sha256(0,sha256,script,n);
calc_rmd160(0,p2sh_rmd160,sha256,sizeof(sha256));
return(n);
}
char *create_atomictx_cltvspend(char *scriptstr,uint8_t *rmd160A,uint8_t *rmd160B,uint32_t locktime)
int32_t bitcoin_p2shscript(uint8_t *script,int32_t n,const uint8_t *p2shscript,const int32_t p2shlen)
{
if ( p2shlen >= 0xfd )
{
script[n++] = 0x4d;
script[n++] = (p2shlen & 0xff);
script[n++] = ((p2shlen >> 8) & 0xff);
}
else
{
script[n++] = 0x4c;
script[n++] = p2shlen;
}
memcpy(&script[n],p2shscript,p2shlen), n += p2shlen;
return(n);
}
int32_t bitcoin_scriptsig(uint8_t *script,int32_t n,const struct vin_info *vp)
{
int32_t i,siglen;
if ( vp->N > 1 )
script[n++] = SCRIPT_OP_NOP;
for (i=0; i<vp->N; i++)
{
if ( (siglen= vp->signers[i].siglen) != 0 )
{
script[n++] = siglen;
memcpy(&script[n],vp->signers[i].sig,siglen), n += siglen;
}
}
if ( vp->type == IGUANA_SCRIPT_P2SH )
n = bitcoin_p2shscript(script,n,vp->p2shscript,vp->p2shlen);
return(n);
}
int32_t bitcoin_cltvscript(uint8_t p2shtype,char *ps2h_coinaddr,uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,char *senderaddr,char *destaddr,uint32_t locktime)
{
// OP_IF
// <timestamp> OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 <hash160> OP_EQUALVERIFY OP_CHECKSIG
// OP_ELSE
// OP_DUP OP_HASH160 <hash160> OP_EQUALVERIFY OP_CHECKSIG // standard spend
// OP_ENDIF
uint8_t hex[4096]; int32_t n = 0;
hex[n++] = SCRIPT_OP_IF;
n = bitcoin_checklocktimeverify(hex,n,locktime);
n = bitcoin_standardspend(hex,n,rmd160A);
hex[n++] = SCRIPT_OP_ELSE;
n = bitcoin_standardspend(hex,n,rmd160B);
hex[n++] = SCRIPT_OP_ENDIF;
init_hexbytes_noT(scriptstr,hex,n);
return(scriptstr);
uint8_t sha256[32],rmd160A[20],rmd160B[20],addrtypeA,addrtypeB;
bitcoin_addr2rmd160(&addrtypeA,rmd160A,senderaddr);
bitcoin_addr2rmd160(&addrtypeB,rmd160B,destaddr);
script[n++] = SCRIPT_OP_IF;
n = bitcoin_checklocktimeverify(script,n,locktime);
n = bitcoin_standardspend(script,n,rmd160A);
script[n++] = SCRIPT_OP_ELSE;
n = bitcoin_standardspend(script,n,rmd160B);
script[n++] = SCRIPT_OP_ENDIF;
vcalc_sha256(0,sha256,script,n);
calc_rmd160(0,p2sh_rmd160,sha256,sizeof(sha256));
bitcoin_address(ps2h_coinaddr,p2shtype,p2sh_rmd160,20);
return(n);
}
int32_t iguana_scriptgen(struct iguana_info *coin,char *coinaddr,uint8_t *script,char *asmstr,uint8_t rmd160[20],uint8_t type,int32_t txi,struct vin_info *vp)
int32_t iguana_scriptgen(struct iguana_info *coin,int32_t *Mp,int32_t *nump,char *coinaddr,uint8_t *script,char *asmstr,uint8_t rmd160[20],uint8_t type,const struct vin_info *vp,int32_t txi)
{
uint8_t addrtype; char rmd160str[41]; int32_t i,m,n,flag = 0,scriptlen = 0;
uint8_t addrtype; char rmd160str[41],pubkeystr[256]; int32_t i,m,n,flag = 0,scriptlen = 0;
m = n = 1;
if ( type == IGUANA_SCRIPT_76A988AC || type == IGUANA_SCRIPT_76AC || type == IGUANA_SCRIPT_P2SH )
{
@ -376,7 +429,6 @@ int32_t iguana_scriptgen(struct iguana_info *coin,char *coinaddr,uint8_t *script
init_hexbytes_noT(rmd160str,rmd160,20);
btc_convrmd160(coinaddr,addrtype,rmd160);
}
//printf("addrtype.%d\n",addrtype);
switch ( type )
{
case IGUANA_SCRIPT_NULL:
@ -385,8 +437,10 @@ int32_t iguana_scriptgen(struct iguana_info *coin,char *coinaddr,uint8_t *script
coinaddr[0] = 0;
break;
case IGUANA_SCRIPT_76AC:
sprintf(asmstr,"OP_DUP %s OP_CHECKSIG // %s",rmd160str,coinaddr);
scriptlen = bitcoin_pubkeyspend(script,0,vp->signers[0].pubkey);
init_hexbytes_noT(pubkeystr,(uint8_t *)vp->signers[0].pubkey,bitcoin_pubkeylen(vp->signers[0].pubkey));
sprintf(asmstr,"OP_DUP %s OP_CHECKSIG // %s",pubkeystr,coinaddr);
scriptlen = bitcoin_pubkeyspend(script,0,(uint8_t *)vp->signers[0].pubkey);
//printf("[%02x] scriptlen.%d (%s)\n",vp->signers[0].pubkey[0],scriptlen,asmstr);
break;
case IGUANA_SCRIPT_76A988AC:
sprintf(asmstr,"OP_DUP OP_HASH160 %s OP_EQUALVERIFY OP_CHECKSIG // %s",rmd160str,coinaddr);
@ -418,11 +472,11 @@ int32_t iguana_scriptgen(struct iguana_info *coin,char *coinaddr,uint8_t *script
}
if ( n > 1 )
{
scriptlen = bitcoin_MofN(rmd160,script,0,vp,m,n);
scriptlen = bitcoin_MofNspendscript(rmd160,script,0,vp);
sprintf(asmstr,"%d ",m);
for (i=0; i<n; i++)
{
init_hexbytes_noT(asmstr + strlen(asmstr),vp->signers[i].pubkey,bitcoin_pubkeylen(vp->signers[i].pubkey));
init_hexbytes_noT(asmstr + strlen(asmstr),(uint8_t *)vp->signers[i].pubkey,bitcoin_pubkeylen(vp->signers[i].pubkey));
strcat(asmstr," ");
}
sprintf(asmstr + strlen(asmstr),"%d // M.%d of N.%d [",n,m,n);
@ -431,8 +485,9 @@ int32_t iguana_scriptgen(struct iguana_info *coin,char *coinaddr,uint8_t *script
strcat(asmstr,"]\n");
}
if ( flag != 0 && vp->spendlen > 0 )
init_hexbytes_noT(asmstr + strlen(asmstr),vp->spendscript,vp->spendlen);
return(0);
init_hexbytes_noT(asmstr + strlen(asmstr),(uint8_t *)vp->spendscript,vp->spendlen);
*Mp = m, *nump = n;
return(scriptlen);
}
int32_t _iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp)
@ -552,19 +607,6 @@ int32_t _iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp)
return(type);
}
/*
struct vin_signer { bits256 privkey; uint8_t siglen,sig[80],rmd160[20],pubkey[66]; };
struct vin_info
{
struct iguana_msgvin vin;
int32_t M,N,validmask,spendlen,p2shflag;
struct vin_signer signers[16];
uint8_t rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE];
};
*/
int32_t iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp,uint8_t *pk_script,int32_t pk_scriptlen,bits256 debugtxid,int32_t vout,uint32_t sequence)
{
int32_t scriptlen; uint8_t script[IGUANA_MAXSCRIPTSIZE]; char asmstr[IGUANA_MAXSCRIPTSIZE*3];
@ -573,10 +615,9 @@ int32_t iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp,uint8_t *
vp->spendlen = pk_scriptlen;
vp->vin.sequence = sequence;
memcpy(vp->spendscript,pk_script,pk_scriptlen);
vp->vin.script = vp->spendscript, vp->vin.prev_vout = pk_scriptlen;
if ( (vp->type= _iguana_calcrmd160(coin,vp)) >= 0 )
{
scriptlen = iguana_scriptgen(coin,vp->coinaddr,script,asmstr,vp->rmd160,vp->type,vout,vp);
scriptlen = iguana_scriptgen(coin,&vp->M,&vp->N,vp->coinaddr,script,asmstr,vp->rmd160,vp->type,(const struct vin_info *)vp,vout);
if ( scriptlen != pk_scriptlen || memcmp(script,pk_script,scriptlen) != 0 )
{
printf("iguana_calcrmd160 type.%d error regenerating scriptlen.%d vs %d\n",vp->type,scriptlen,pk_scriptlen);
@ -614,7 +655,7 @@ int32_t iguana_parsevinobj(struct iguana_info *coin,uint8_t *serialized,int32_t
vin->prev_hash = jbits256(vinobj,"txid");
vin->prev_vout = jint(vinobj,"vout");
if ( (sigjson= jobj(vinobj,"scriptSig")) != 0 )
hexstr = jstr(sigjson,"redeemScript");
hexstr = jstr(sigjson,"hex");
}
if ( hexstr != 0 )
{
@ -631,46 +672,42 @@ int32_t iguana_parsevinobj(struct iguana_info *coin,uint8_t *serialized,int32_t
return(len);
}
//{"result":{"txid":"a2b81b9894205ced12dfe276cbe27c05308976b5a2e12789ccd167fe6c3217f7","version":1,"time":1433295027,"locktime":0,"vin":[{"txid":"cf8f5e26e29a74c4fb867338213c02059b975fcfeae993926edbad8aba1cfedb","vout":1,"scriptSig":{"asm":"3045022100f86ab6815d1c22bf9f0fb6c389b558eb644159462054039d393cdba6e480a952022079b7f804c48a0ef5de68bc4be4c18cd5ea947763f4d5f6d415092f8dc00ee1aa01","hex":"483045022100f86ab6815d1c22bf9f0fb6c389b558eb644159462054039d393cdba6e480a952022079b7f804c48a0ef5de68bc4be4c18cd5ea947763f4d5f6d415092f8dc00ee1aa01"},"sequence":4294967295},{"txid":"cfcaef36853be671a5247c1ccb2a54a59d8b4628d0d63726dcdc8dbf73116ae3","vout":2,"scriptSig":{"asm":"3045022100a84f56626e4558e13911290e72d498796ba0bc70a0c9eb59b20d50f6ed94cee30220734c94ab1e89dfe26b3cc1b519a5a6f37863829e9eccdb246843e76577b4040f01","hex":"483045022100a84f56626e4558e13911290e72d498796ba0bc70a0c9eb59b20d50f6ed94cee30220734c94ab1e89dfe26b3cc1b519a5a6f37863829e9eccdb246843e76577b4040f01"},"sequence":4294967295}],"vout":[{"value":0.00000000,"n":0,"scriptPubKey":{"asm":"","type":"nonstandard"}},{"value":1036.57541260,"n":1,"scriptPubKey":{"asm":"03506a52e95cdfbb9d17d702af6259ba7de8b7a604007999e0266edbf6e4bb6974 OP_CHECKSIG","reqSigs":1,"type":"pubkey","addresses":["RJyYWRKSK7cMg5EeW9aHAaT3hHVEkAXnP9"]}}],"blockhash":"6863f2bab8cd9b69dd7a446aa63281f9e5301520f9ba02ca3acc892866872fe4","confirmations":374485},"error":null,"id":"jl777"}
//{"result":{"version":1,"timestamp":1433295027,"vin":[{"sequence":4294967295,"txid":"cf8f5e26e29a74c4fb867338213c02059b975fcfeae993926edbad8aba1cfedb","vout":1,"hex":"483045022100f86ab6815d1c22bf9f0fb6c389b558eb644159462054039d393cdba6e480a952022079b7f804c48a0ef5de68bc4be4c18cd5ea947763f4d5f6d415092f8dc00ee1aa01"}, {"sequence":4294967295,"txid":"cfcaef36853be671a5247c1ccb2a54a59d8b4628d0d63726dcdc8dbf73116ae3","vout":2,"hex":"483045022100a84f56626e4558e13911290e72d498796ba0bc70a0c9eb59b20d50f6ed94cee30220734c94ab1e89dfe26b3cc1b519a5a6f37863829e9eccdb246843e76577b4040f01"}],"numvins":2,"vout":[{"value":0,"n":0,"scriptPubKey":{"asm":"coinbase","addresses":[]}}, {"value":1036.57541260,"n":1,"scriptPubKey":{"asm":"OP_DUP 6a5ad2f911f1bfd7c018c95154e2c049accd04da OP_CHECKSIG","addresses":["RJyYWRKSK7cMg5EeW9aHAaT3hHVEkAXnP9"],"hex":"2103506a52e95cdfbb9d17d702af6259ba7de8b7a604007999e0266edbf6e4bb6974ac"}}],"numvouts":2,"locktime":0,"size":295,"txid":"a2b81b9894205ced12dfe276cbe27c05308976b5a2e12789ccd167fe6c3217f7"},"height":555555,"confirmations":333945,"blockhash":"6863f2bab8cd9b69dd7a446aa63281f9e5301520f9ba02ca3acc892866872fe4","tag":"731886559821890929"}
cJSON *iguana_voutjson(struct iguana_info *coin,struct iguana_msgvout *vout,int32_t txi,bits256 txid)
{
// 035f1321ed17d387e4433b2fa229c53616057964af065f98bfcae2233c5108055e OP_CHECKSIG
char scriptstr[8192+1],coinaddr[65],asmstr[16384]; int32_t i,asmtype; struct vin_info V;
uint8_t addrtype,space[8192];
cJSON *addrs,*skey,*json = cJSON_CreateObject();
char scriptstr[8192+1],asmstr[16384]; int32_t i,m,n,scriptlen,asmtype; struct vin_info *vp;
uint8_t space[8192]; cJSON *addrs,*skey,*json = cJSON_CreateObject();
vp = calloc(1,sizeof(*vp));
jaddnum(json,"value",dstr(vout->value));
jaddnum(json,"n",txi);
//"scriptPubKey":{"asm":"OP_DUP OP_HASH160 5f69cb73016264270dae9f65c51f60d0e4d6fd44 OP_EQUALVERIFY OP_CHECKSIG","reqSigs":1,"type":"pubkeyhash","addresses":["RHyh1V9syARTf2pyxibz7v27D5paBeWza5"]}
if ( vout->pk_script != 0 && vout->pk_scriptlen*2+1 < sizeof(scriptstr) )
{
memset(&V,0,sizeof(V));
if ( (asmtype= iguana_calcrmd160(coin,&V,vout->pk_script,vout->pk_scriptlen,txid,txi,0xffffffff)) >= 0 )
memset(vp,0,sizeof(*vp));
if ( (asmtype= iguana_calcrmd160(coin,vp,vout->pk_script,vout->pk_scriptlen,txid,txi,0xffffffff)) >= 0 )
{
skey = cJSON_CreateObject();
addrtype = iguana_scriptgen(coin,V.coinaddr,space,asmstr,V.rmd160,asmtype,txi,&V);
scriptlen = iguana_scriptgen(coin,&m,&n,vp->coinaddr,space,asmstr,vp->rmd160,asmtype,vp,txi);
if ( asmstr[0] != 0 )
jaddstr(skey,"asm",asmstr);
addrs = cJSON_CreateArray();
if ( V.M == 0 )
if ( vp->N == 1 )
{
if ( asmtype == 2 )
{
jaddnum(skey,"reqSigs",1);
jaddstr(skey,"type","pubkeyhash");
}
if ( coinaddr[0] != 0 )
jaddistr(addrs,coinaddr);
if ( vp->coinaddr[0] != 0 )
jaddistr(addrs,vp->coinaddr);
}
else
{
jaddnum(skey,"reqSigs",V.M);
for (i=0; i<V.N; i++)
jaddnum(skey,"reqSigs",vp->M);
for (i=0; i<vp->N; i++)
{
btc_convrmd160(coinaddr,coin->chain->pubtype,V.signers[i].pubkey);
jaddistr(addrs,coinaddr);
//btc_convrmd160(coinaddr,coin->chain->pubtype,V.signers[i].pubkey);
jaddistr(addrs,vp->signers[i].coinaddr);
}
}
jadd(skey,"addresses",addrs);
@ -697,41 +734,13 @@ cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin)
jaddstr(json,"txid",bits256_str(str,vin->prev_hash));
jaddnum(json,"vout",vout);
sigjson = cJSON_CreateObject();
jaddstr(sigjson,"redeemScript",scriptstr);
jaddstr(sigjson,"hex",scriptstr);
jadd(json,"scriptSig",sigjson);
}
return(json);
}
cJSON *iguana_txjson(struct iguana_info *coin,struct iguana_txid *tx,int32_t height)
{
struct iguana_msgvin vin; struct iguana_msgvout vout; int32_t i; char asmstr[512],str[65]; uint8_t space[8192];
cJSON *vouts,*vins,*json;
json = cJSON_CreateObject();
jaddstr(json,"txid",bits256_str(str,tx->txid));
if ( height >= 0 )
jaddnum(json,"height",height);
jaddnum(json,"version",tx->version);
jaddnum(json,"timestamp",tx->timestamp);
jaddnum(json,"locktime",tx->locktime);
vins = cJSON_CreateArray();
vouts = cJSON_CreateArray();
for (i=0; i<tx->numvouts; i++)
{
iguana_voutset(coin,space,asmstr,height,&vout,tx,i);
jaddi(vouts,iguana_voutjson(coin,&vout,i,tx->txid));
}
jadd(json,"vout",vouts);
for (i=0; i<tx->numvins; i++)
{
iguana_vinset(coin,height,&vin,tx,i);
jaddi(vins,iguana_vinjson(coin,&vin));
}
jadd(json,"vin",vins);
return(json);
}
int32_t iguana_vinparse(int32_t rwflag,uint8_t *serialized,struct iguana_msgvin *msg)
int32_t iguana_vinparse(struct iguana_info *coin,int32_t rwflag,uint8_t *serialized,struct iguana_msgvin *msg)
{
int32_t len = 0;
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->prev_hash),msg->prev_hash.bytes);
@ -803,7 +812,7 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t rwflag,cJSON *json,uint8
{
for (i=0; i<msg->tx_in; i++)
{
len += iguana_vinparse(rwflag,&serialized[len],&msg->vins[i]);
len += iguana_vinparse(coin,rwflag,&serialized[len],&msg->vins[i]);
if ( array != 0 )
jaddi(array,iguana_vinjson(coin,&msg->vins[i]));
}
@ -880,7 +889,7 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t rwflag,cJSON *json,uint8
return(len);
}
bits256 iguana_parsetxobj(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,cJSON *txobj)
bits256 iguana_parsetxobj(struct iguana_info *coin,int32_t *txstartp,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,cJSON *txobj) // json -> serialized + (msg,V)
{
int32_t i,numvins,numvouts,len = 0; cJSON *array=0; bits256 txid; char vpnstr[64];
memset(msg,0,sizeof(*msg));
@ -916,125 +925,166 @@ bits256 iguana_parsetxobj(struct iguana_info *coin,uint8_t *serialized,int32_t m
}
msg->lock_time = juint(txobj,"locktime");
msg->txid = jbits256(txobj,"txid");
*txstartp = len;
msg->allocsize = iguana_rwmsgtx(coin,1,0,&serialized[len],maxsize-len,msg,&txid,vpnstr);
//char str[65]; printf("json -> %s\n",bits256_str(str,txid));
return(txid);
}
char *iguana_rawtxbytes(struct iguana_info *coin,uint8_t *serialized,int32_t datalen,cJSON *json,struct iguana_msgtx *msgtx)
char *iguana_rawtxbytes(struct iguana_info *coin,cJSON *json,struct iguana_msgtx *msgtx)
{
int32_t n; char *txbytes,vpnstr[64];
int32_t n; char *txbytes = 0,vpnstr[64]; uint8_t *serialized;
serialized = malloc(IGUANA_MAXPACKETSIZE);
vpnstr[0] = 0;
//char str[65]; printf("%d of %d: %s\n",i,msg.txn_count,bits256_str(str,tx.txid));
if ( (n= iguana_rwmsgtx(coin,1,json,serialized,datalen,msgtx,&msgtx->txid,vpnstr)) > 0 )
if ( (n= iguana_rwmsgtx(coin,1,json,serialized,IGUANA_MAXPACKETSIZE,msgtx,&msgtx->txid,vpnstr)) > 0 )
{
txbytes = malloc(n*2+1);
init_hexbytes_noT(txbytes,serialized,n);
return(txbytes);
}
return(0);
free(serialized);
return(txbytes);
}
cJSON *bitcoin_txjson(struct iguana_info *coin,struct iguana_msgtx *msgtx)
/*
struct vin_signer { bits256 privkey; uint8_t siglen,sig[80],rmd160[20],pubkey[66]; };
struct vin_info
{
struct iguana_msgvin vin;
int32_t M,N,validmask,spendlen,p2shflag;
struct vin_signer signers[16];
uint8_t rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE];
};
*/
int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t type)
{
char vpnstr[2]; int32_t n; uint8_t *serialized; bits256 txid; cJSON *json = cJSON_CreateObject();
vpnstr[0] = 0;
serialized = malloc(IGUANA_MAXPACKETSIZE);
if ( (n= iguana_rwmsgtx(coin,1,json,serialized,IGUANA_MAXPACKETSIZE,msgtx,&txid,vpnstr)) < 0 )
char asmstr[IGUANA_MAXSCRIPTSIZE*3]; int32_t j,n,siglen,plen; uint8_t sha256[32];
j = n = 0;
*hashtypep = SIGHASH_ALL;
while ( (siglen= scriptsig[n]) >= 70 && siglen <= 73 && n+siglen+1 < len && j < 16 )
{
printf("bitcoin_txtest: n.%d\n",n);
vp->signers[j].siglen = siglen;
memcpy(vp->signers[j].sig,&scriptsig[n+1],siglen);
if ( j == 0 )
*hashtypep = vp->signers[j].sig[siglen-1];
n += (siglen + 1);
j++;
if ( type == 0 && j > 1 )
type = IGUANA_SCRIPT_MSIG;
}
free(serialized);
return(json);
}
int32_t bitcoin_outputscript(struct iguana_info *coin,char *pubkeys[],int32_t *scriptlenp,uint8_t *scriptspace,bits256 txid,int32_t vout)
{
struct iguana_txid T,*tx; int32_t height,numpubs = 1; char asmstr[8192]; struct iguana_msgvout v;
if ( 0 )
vp->type = type;
j = 0;
while ( ((plen= scriptsig[n]) == 33 || plen == 65 ) && j < 16 )
{
*scriptlenp = 0;
if ( (tx= iguana_txidfind(coin,&height,&T,txid)) != 0 )
{
*scriptlenp = iguana_voutset(coin,scriptspace,asmstr,height,&v,tx,vout);
return(numpubs);
}
memcpy(vp->signers[j].pubkey,&scriptsig[n+1],plen);
vcalc_sha256(0,sha256,vp->signers[j].pubkey,plen);
calc_rmd160(0,vp->signers[j].rmd160,sha256,sizeof(sha256));
if ( j == 0 )
memcpy(vp->rmd160,vp->signers[j].rmd160,20);
n += (plen + 1);
j++;
}
//char *str = "2103506a52e95cdfbb9d17d702af6259ba7de8b7a604007999e0266edbf6e4bb6974ac";
char *str = "76a914010966776006953d5567439e5e39f86a0d273bee88ac";
*scriptlenp = (int32_t)strlen(str) >> 1;
decode_hex(scriptspace,*scriptlenp,str);
//pubkeys[0] = clonestr("03506a52e95cdfbb9d17d702af6259ba7de8b7a604007999e0266edbf6e4bb6974");
pubkeys[0] = clonestr("0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6");
return(numpubs);
}
int32_t bitcoin_hashtype(uint8_t *script,int32_t scriptlen,uint8_t *pk_script,int32_t pk_scriptlen)
{
return(SIGHASH_ALL);
if ( n < len && (scriptsig[n] == 0x4c || scriptsig[n] == 0x4d) )
{
if ( scriptsig[n] == 0x4c )
vp->p2shlen = scriptsig[n+1], n += 2;
else vp->p2shlen = ((uint32_t)scriptsig[n+1] + ((uint32_t)scriptsig[n+2] << 8)), n += 3;
memcpy(vp->p2shscript,&scriptsig[n],vp->p2shlen);
vp->type = IGUANA_SCRIPT_P2SH;
}
/*if ( len == 0 )
{
// txid.(eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2).v1
decode_hex(vp->rmd160,20,"010966776006953d5567439e5e39f86a0d273bee");//3564a74f9ddb4372301c49154605573d7d1a88fe");
vp->type = IGUANA_SCRIPT_76A988AC;
}*/
vp->spendlen = iguana_scriptgen(coin,&vp->M,&vp->N,vp->coinaddr,vp->spendscript,asmstr,vp->rmd160,vp->type,(const struct vin_info *)vp,vp->vin.prev_vout);
//printf("type.%d asmstr.(%s) spendlen.%d\n",vp->type,asmstr,vp->spendlen);
return(vp->spendlen);
}
int32_t bitcoin_verifyvins(struct iguana_info *coin,int32_t *scriptlens,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxsize,bits256 myprivkey)
int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,int32_t *scriptlens,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxsize,struct vin_info *V)
{
char txidstr[128],bigstr[2560],coinaddr[64],vpnstr[64],str[65],*pubkeys[16];
uint8_t *sig,mypubkey[128],pubkey[128],sigspace[8192],*saveinput,scriptspace[8192];
bits256 txid,sigtxid,revsigtxid,mypub;
int32_t n2,i,j,numpubs,plen,scriptlen,vini=0,siglen,numvins,hashtype,myvin = 1;
bits256 txid,sigtxid,revsigtxid; char txidstr[128],bigstr[2560],coinaddr[64],vpnstr[64],str[65];
uint8_t *sig,*pubkey,*saveinput; struct vin_info *vp;
int32_t n2,i,j,k,plen,vini=0,flag,numvins,hashtype,retval,siglen,asmtype;
vpnstr[0] = 0;
memset(pubkeys,0,sizeof(pubkeys));
*signedtx = 0;
memset(signedtxidp,0,sizeof(*signedtxidp));
numvins = msgtx->tx_in;
mypub = bitcoin_pubkey(mypubkey,myprivkey);
retval = -numvins;
for (vini=0; vini<numvins; vini++)
{
saveinput = msgtx->vins[vini].script;
vp = &V[vini];
for (i=0; i<numvins; i++)
msgtx->vins[i].scriptlen = 0;
saveinput = msgtx->vins[vini].script;
sig = &msgtx->vins[vini].script[1];
siglen = msgtx->vins[vini].script[0];
numpubs = bitcoin_outputscript(coin,pubkeys,&scriptlen,scriptspace,msgtx->vins[vini].prev_hash,msgtx->vins[vini].prev_vout);
msgtx->vins[vini].scriptlen = scriptlen;
msgtx->vins[vini].script = scriptspace;
for (j=0; j<numpubs; j++)
siglen = msgtx->vins[vini].script[0] - 1;
vp->vin = msgtx->vins[vini];
flag = 0;
for (k=0; k<2; k++)
{
plen = (int32_t)strlen(pubkeys[j]);
plen >>= 1;
decode_hex(pubkey,plen,pubkeys[j]);
bitcoin_address(coinaddr,coin->chain->pubtype,pubkey,plen);
n2 = iguana_rwmsgtx(coin,1,0,serialized,maxsize,msgtx,&txid,vpnstr);
hashtype = bitcoin_hashtype(saveinput,scriptlens[vini],scriptspace,scriptlen);
msgtx->vins[vini].script = saveinput;
if ( n2 > 0 )
asmtype = (k == 0) ? IGUANA_SCRIPT_76A988AC : IGUANA_SCRIPT_76AC;
if ( bitcoin_scriptget(coin,&hashtype,vp,saveinput,scriptlens[vini],asmtype) < 0 )
{
n2 += iguana_rwnum(1,&serialized[n2],sizeof(hashtype),&hashtype);
revsigtxid = bits256_doublesha256(txidstr,serialized,n2);
for (i=0; i<sizeof(revsigtxid); i++)
sigtxid.bytes[31-i] = revsigtxid.bytes[i];
if ( 1 && myvin != 0 )
printf("cant get script for (%s).v%d\n",bits256_str(str,vp->vin.prev_hash),vp->vin.prev_vout);
continue;
}
msgtx->vins[vini].script = vp->spendscript;
msgtx->vins[vini].scriptlen = vp->spendlen;
for (j=0; j<vp->N; j++)
{
pubkey = vp->signers[j].pubkey;
if ( (plen= bitcoin_pubkeylen(pubkey)) < 0 )
{
sig = sigspace;
siglen = bitcoin_sign(sig,sizeof(sigspace),sigtxid.bytes,sizeof(sigtxid),myprivkey);
printf("plen.%d siglen.%d %s\n",plen,siglen,bits256_str(str,myprivkey));
msgtx->vins[vini].scriptlen = siglen + plen + 2;
msgtx->vins[vini].script[0] = siglen;
memcpy(msgtx->vins[vini].script+1,sigspace,siglen);
msgtx->vins[vini].script[siglen + 1] = plen;
memcpy(msgtx->vins[vini].script+1+siglen+1,pubkey,plen);
cJSON *j = cJSON_CreateObject();
char *txstr = iguana_rawtxbytes(coin,malloc(10000),10000,j,msgtx);
printf("SIGNEDTX.(%s) %s\n",txstr,jprint(j,0));
siglen++;
//printf("retjson.(%s) %p\n",jprint(retjson,0),retjson);
printf("illegal plen.%d [%02x]\n",plen,pubkey[0]);
break;
}
if ( bitcoin_verify(sig,siglen-1,sigtxid.bytes,sizeof(sigtxid),0,pubkey,plen) < 0 )
bitcoin_address(coinaddr,coin->chain->pubtype,pubkey,plen);
n2 = iguana_rwmsgtx(coin,1,0,serialized,maxsize,msgtx,&txid,vpnstr);
msgtx->vins[vini].script = saveinput;
if ( n2 > 0 )
{
init_hexbytes_noT(bigstr,serialized,n2);
printf("(%s) doesnt verify hash2.%s\n",bigstr,bits256_str(str,sigtxid));
return(-1);
} else printf("SIG.%d VERIFIED\n",vini);
} else return(-1);
n2 += iguana_rwnum(1,&serialized[n2],sizeof(hashtype),&hashtype);
revsigtxid = bits256_doublesha256(txidstr,serialized,n2);
for (i=0; i<sizeof(revsigtxid); i++)
sigtxid.bytes[31-i] = revsigtxid.bytes[i];
if ( 1 && bits256_nonz(vp->signers[j].privkey) != 0 )
{
vp->signers[j].siglen = bitcoin_sign(vp->signers[j].sig,sizeof(vp->signers[j].sig),sigtxid.bytes,sizeof(sigtxid),vp->signers[j].privkey);
sig = vp->signers[j].sig;
siglen = vp->signers[j].siglen;
msgtx->vins[vini].scriptlen = bitcoin_scriptsig(msgtx->vins[vini].script,0,(const struct vin_info *)vp);
printf("SIGNEDTX plen.%d siglen.%d\n",plen,siglen);
}
if ( bitcoin_verify(sig,siglen,sigtxid.bytes,sizeof(sigtxid),0,vp->signers[j].pubkey,bitcoin_pubkeylen(vp->signers[j].pubkey)) < 0 )
{
init_hexbytes_noT(bigstr,serialized,n2);
printf("(%s) doesnt verify hash2.%s\n",bigstr,bits256_str(str,sigtxid));
}
else
{
printf("SIG.%d VERIFIED\n",vini);
*signedtx = iguana_rawtxbytes(coin,0,msgtx);
*signedtxidp = msgtx->txid;
flag = 1;
break;
}
} else printf("bitcoin_verifyvins: vini.%d n2.%d\n",vini,n2);
}
if ( flag > 0 )
{
retval++;
break;
}
if ( vp->type != IGUANA_SCRIPT_76A988AC && vp->type != IGUANA_SCRIPT_76AC )
break;
}
}
return(0);
return(retval);
}
//printf("privkey.%s\n",bits256_str(str,privkey));
@ -1052,17 +1102,16 @@ ffffffff\
76a914097072524438d003d23a2f23edb65aae1bb3e46988ac\
00000000";
int32_t bitcoin_verifytx(struct iguana_info *coin,char *rawtxstr)
int32_t bitcoin_verifytx(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,char *rawtxstr,struct vin_info *V)
{
int32_t i,len,maxsize,*scriptlens,numvins,retval = -1; uint8_t *serialized,*serialized2;
struct iguana_msgtx msgtx; bits256 txid,myprivkey; char vpnstr[64];
struct iguana_msgtx msgtx; bits256 txid; char vpnstr[64];
len = (int32_t)strlen(rawtxstr);
maxsize = len + 32768;
serialized = calloc(1,maxsize);
serialized2 = calloc(1,maxsize);
len >>= 1;
vpnstr[0] = 0;
decode_hex(myprivkey.bytes,sizeof(myprivkey),"18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725");
decode_hex(serialized,len,rawtxstr);
memset(&msgtx,0,sizeof(msgtx));
if ( iguana_rwmsgtx(coin,0,0,serialized,maxsize,&msgtx,&txid,vpnstr) > 0 )
@ -1071,27 +1120,144 @@ decode_hex(myprivkey.bytes,sizeof(myprivkey),"18E14A7B6A307F426A94F8114701E7C8E7
scriptlens = calloc(numvins,sizeof(*scriptlens));
for (i=0; i<numvins; i++)
scriptlens[i] = msgtx.vins[i].scriptlen;
if ( bitcoin_verifyvins(coin,scriptlens,&msgtx,serialized2,maxsize,myprivkey) == 0 )
if ( bitcoin_verifyvins(coin,signedtxidp,signedtx,scriptlens,&msgtx,serialized2,maxsize,V) == 0 )
retval = 0;
else printf("bitcoin_verifytx: bitcoin_verifyvins error\n");
for (i=0; i<numvins; i++)
msgtx.vins[i].scriptlen = scriptlens[i];
free(scriptlens);
}
} else printf("bitcoin_verifytx: error iguana_rwmsgtx\n");
free(serialized), free(serialized2);
return(retval);
}
char *bitcoin_json2hex(struct iguana_info *coin,bits256 *txidp,cJSON *txjson)
{
int32_t txstart; uint8_t *serialized; struct iguana_msgtx msgtx; char *txbytes = 0;
serialized = malloc(IGUANA_MAXPACKETSIZE);
*txidp = iguana_parsetxobj(coin,&txstart,serialized,IGUANA_MAXPACKETSIZE,&msgtx,txjson);
if ( msgtx.allocsize != 0 )
{
txbytes = malloc(msgtx.allocsize*2 + 1);
init_hexbytes_noT(txbytes,&serialized[txstart],msgtx.allocsize);
} else printf("bitcoin_txtest: zero msgtx allocsize\n");
free(serialized);
return(txbytes);
}
cJSON *bitcoin_createtx(struct iguana_info *coin,int32_t lockduration)
{
uint32_t timestamp; cJSON *json = cJSON_CreateObject();
timestamp = (uint32_t)time(NULL) + 5;
if ( lockduration == 0 )
{
jaddnum(json,"version",1);
jaddnum(json,"locktime",0);
}
else
{
jaddnum(json,"version",4);
jaddnum(json,"locktime",timestamp + lockduration);
}
if ( coin->chain->hastimestamp != 0 )
jaddnum(json,"timestamp",timestamp);
jadd(json,"vin",cJSON_CreateArray());
jadd(json,"vout",cJSON_CreateArray());
return(json);
}
cJSON *bitcoin_addoutput(struct iguana_info *coin,cJSON *txobj,uint8_t *paymentscript,int32_t len,double amount)
{
char *hexstr; cJSON *item,*skey,*vouts = jduplicate(jobj(txobj,"vout"));
item = cJSON_CreateObject();
jaddnum(item,"value",amount);
skey = cJSON_CreateObject();
hexstr = malloc(len*2 + 1);
init_hexbytes_noT(hexstr,paymentscript,len);
jaddstr(skey,"hex",hexstr);
free(hexstr);
jadd(item,"scriptPubkey",skey);
jdelete(vouts,"vout");
jadd(vouts,"vout",item);
return(txobj);
}
cJSON *bitcoin_addinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequence)
{
cJSON *item,*vins = jduplicate(jobj(txobj,"vin"));
item = cJSON_CreateObject();
jaddbits256(item,"txid",txid);
jaddnum(item,"vout",vout);
jaddnum(item,"sequence",sequence);
jdelete(vins,"vin");
jadd(vins,"vin",item);
return(txobj);
}
char *bitcoin_cltvtx(struct iguana_info *coin,char *changeaddr,char *senderaddr,char *destaddr,int32_t duration,double amount,bits256 txid,int32_t vout,uint64_t inputsatoshis,bits256 privkey)
{
uint64_t change,satoshis; char *rawtxstr,*signedtx; struct vin_info V; bits256 cltxid,signedtxid;
int32_t cltvlen,len; uint32_t timestamp,locktime; char ps2h_coinaddr[65]; cJSON *txobj;
uint8_t p2sh_rmd160[20],cltvscript[1024],paymentscript[64],rmd160[20],addrtype;
timestamp = (uint32_t)time(NULL);
locktime = timestamp + duration;
cltvlen = bitcoin_cltvscript(coin->chain->p2shtype,ps2h_coinaddr,p2sh_rmd160,cltvscript,0,senderaddr,destaddr,locktime);
txobj = bitcoin_createtx(coin,duration);
len = bitcoin_p2shspend(paymentscript,0,p2sh_rmd160);
satoshis = (amount * SATOSHIDEN);
bitcoin_addoutput(coin,txobj,paymentscript,len,amount);
bitcoin_addinput(coin,txobj,txid,vout,locktime);
if ( inputsatoshis > (satoshis + 10000) )
{
change = inputsatoshis - (satoshis + 10000);
if ( changeaddr != 0 && changeaddr[0] != 0 )
{
bitcoin_addr2rmd160(&addrtype,rmd160,changeaddr);
if ( addrtype == coin->chain->pubtype )
len = bitcoin_standardspend(paymentscript,0,rmd160);
else if ( addrtype == coin->chain->p2shtype )
len = bitcoin_standardspend(paymentscript,0,rmd160);
else
{
printf("error with mismatched addrtype.%02x vs (%02x %02x)\n",addrtype,coin->chain->pubtype,coin->chain->p2shtype);
return(0);
}
bitcoin_addoutput(coin,txobj,paymentscript,len,change);
}
else
{
printf("error no change address when there is change\n");
return(0);
}
}
rawtxstr = bitcoin_json2hex(coin,&cltxid,txobj);
char str[65]; printf("CLTV.%s (%s)\n",bits256_str(str,cltxid),rawtxstr);
memset(&V,0,sizeof(V));
V.signers[0].privkey = privkey;
bitcoin_verifytx(coin,&signedtxid,&signedtx,rawtxstr,&V);
free(rawtxstr);
if ( signedtx != 0 )
printf("signed CLTV.%s (%s)\n",bits256_str(str,signedtxid),signedtx);
else printf("error generating signedtx\n");
free_json(txobj);
return(signedtx);
}
cJSON *bitcoin_txtest(struct iguana_info *coin,char *rawtxstr,bits256 txid)
{
struct iguana_msgtx msgtx; char str[65],str2[65]; bits256 checktxid,blockhash,myprivkey;
struct iguana_msgtx msgtx; char str[65],str2[65]; bits256 checktxid,blockhash,signedtxid;
cJSON *retjson,*txjson; uint8_t *serialized,*serialized2; struct iguana_txid T,*tp;
char vpnstr[64]; int32_t n,i,*scriptlens,height,n2,maxsize,len = (int32_t)strlen(rawtxstr);
struct vin_info *V; char vpnstr[64],*txbytes,*signedtx; int32_t n,txstart,height,n2,maxsize,len;
len = (int32_t)strlen(rawtxstr);
rawtxstr = refstr;
maxsize = len + 32768;
serialized = calloc(1,maxsize);
serialized2 = calloc(1,maxsize);
len >>= 1;
V = 0;
vpnstr[0] = 0;
decode_hex(myprivkey.bytes,sizeof(myprivkey),"18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725");
memset(&msgtx,0,sizeof(msgtx));
if ( len < maxsize )
{
decode_hex(serialized,len,rawtxstr);
@ -1103,16 +1269,16 @@ decode_hex(myprivkey.bytes,sizeof(myprivkey),"18E14A7B6A307F426A94F8114701E7C8E7
free(serialized), free(serialized2);
return(cJSON_Parse("{\"error\":\"cant parse txbytes\"}"));
}
scriptlens = calloc(msgtx.tx_in,sizeof(*scriptlens));
for (i=0; i<msgtx.tx_in; i++)
scriptlens[i] = msgtx.vins[i].scriptlen;
if ( bitcoin_verifyvins(coin,scriptlens,&msgtx,serialized2,maxsize,myprivkey) < 0 )
printf("sig verification error\n");
else printf("sigs verified\n");
for (i=0; i<msgtx.tx_in; i++)
msgtx.vins[i].scriptlen = scriptlens[i];
free(scriptlens);
V = calloc(msgtx.tx_in,sizeof(*V));
{
//char *pstr; int32_t plen;
decode_hex(V[0].signers[0].privkey.bytes,sizeof(V[0].signers[0].privkey),"18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725");
//pstr = "0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6";
//plen = (int32_t)strlen(pstr);
//decode_hex(V[0].signers[0].pubkey,plen,pstr);
}
if ( bitcoin_verifytx(coin,&signedtxid,&signedtx,rawtxstr,V) != 0 )
printf("bitcoin_verifytx error\n");
jadd(retjson,"result",txjson);
if ( (tp= iguana_txidfind(coin,&height,&T,txid)) != 0 )
{
@ -1129,64 +1295,34 @@ decode_hex(myprivkey.bytes,sizeof(myprivkey),"18E14A7B6A307F426A94F8114701E7C8E7
if ( (n2= iguana_rwmsgtx(coin,1,0,serialized2,maxsize,&msgtx,&checktxid,vpnstr)) < 0 || n != n2 )
{
printf("bitcoin_txtest: n.%d vs n2.%d\n",n,n2);
free(serialized), free(serialized2);
free(serialized), free(serialized2), free(V);
return(retjson);
}
if ( bits256_cmp(checktxid,txid) != 0 )
{
printf("bitcoin_txtest: txid.%s vs check.%s\n",bits256_str(str,txid),bits256_str(str2,checktxid));
}
checktxid = iguana_parsetxobj(coin,serialized,maxsize,&msgtx,jobj(retjson,"result"));
checktxid = iguana_parsetxobj(coin,&txstart,serialized,maxsize,&msgtx,jobj(retjson,"result"));
if ( bits256_cmp(checktxid,txid) != 0 )
{
printf("bitcoin_txtest: txid.%s vs check2.%s\n",bits256_str(str,txid),bits256_str(str2,checktxid));
}
free(serialized), free(serialized2);
if ( msgtx.allocsize != 0 )
{
txbytes = malloc(msgtx.allocsize*2 + 1);
init_hexbytes_noT(txbytes,&serialized[txstart],msgtx.allocsize);
if ( strcmp(txbytes,rawtxstr) != 0 )
printf("bitcoin_txtest: reconstruction error: %s != %s\n",rawtxstr,txbytes);
else printf("reconstruction PASSED\n");
free(txbytes);
} else printf("bitcoin_txtest: zero msgtx allocsize\n");
free(serialized), free(serialized2), free(V);
return(retjson);
}
free(serialized), free(serialized2);
return(cJSON_Parse("{\"error\":\"testing bitcoin txbytes\"}"));
}
/*{
for (i=0; i<T->numinputs; i++)
strcpy(T->inputs[i].sigs,"00");
strcpy(vin->sigs,redeemscript);
vin->sequence = (uint32_t)-1;
T->nlocktime = 0;
//disp_cointx(&T);
emit_cointx(&hash2,data,sizeof(data),T,oldtx_format,SIGHASH_ALL);
//printf("HASH2.(%llx)\n",(long long)hash2.txid);
if ( bp_sign(&key,hash2.bytes,sizeof(hash2),&sig,&siglen) != 0 )
{
memcpy(sigbuf,sig,siglen);
sigbuf[siglen++] = SIGHASH_ALL;
init_hexbytes_noT(sigs[privkeyind],sigbuf,(int32_t)siglen);
strcpy(vin->sigs,"00");
for (i=0; i<n; i++)
{
if ( sigs[i][0] != 0 )
{
sprintf(vin->sigs + strlen(vin->sigs),"%02x%s",(int32_t)strlen(sigs[i])>>1,sigs[i]);
//printf("(%s).%ld ",sigs[i],strlen(sigs[i]));
}
}
len = (int32_t)(strlen(redeemscript)/2);
if ( len >= 0xfd )
sprintf(&vin->sigs[strlen(vin->sigs)],"4d%02x%02x",len & 0xff,(len >> 8) & 0xff);
else sprintf(&vin->sigs[strlen(vin->sigs)],"4c%02x",len);
sprintf(&vin->sigs[strlen(vin->sigs)],"%s",redeemscript);
//printf("after A.(%s) othersig.(%s) siglen.%02lx -> (%s)\n",hexstr,othersig != 0 ? othersig : "",siglen,vin->sigs);
//printf("vinsigs.(%s) %ld\n",vin->sigs,strlen(vin->sigs));
_emit_cointx(hexstr,sizeof(hexstr),T,oldtx_format);
//disp_cointx(&T);
free(T);
return(clonestr(hexstr));
}
else printf("error signing\n");
free(T);
}*/
#define EXCHANGE_NAME "bitcoin"
#define UPDATE bitcoin ## _price
#define SUPPORTS bitcoin ## _supports
@ -1250,7 +1386,11 @@ char *CANCELORDER(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson
char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson)
{
return(clonestr("{\"error\":\"bitcoin is not yet\"}"));
cJSON *retjson,*array = cJSON_CreateArray();
retjson = cJSON_CreateObject();
instantdex_acceptable(SuperNET_MYINFO(0),array,"","*","*",0);
jadd(retjson,"result",array);
return(jprint(retjson,1));
}
char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson)

1
iguana/exchanges/bitcoin.h

@ -22,6 +22,7 @@
#define SIGHASH_SINGLE 3
#define SIGHASH_ANYONECANPAY 0x80
#define SCRIPT_OP_NOP 0x00
#define SCRIPT_OP_TRUE 0x51
#define SCRIPT_OP_2 0x52
#define SCRIPT_OP_3 0x53

180
iguana/exchanges/nxtae.c

@ -13,13 +13,13 @@
* *
******************************************************************************/
#define NXT_ASSETID ('N' + ((uint64_t)'X'<<8) + ((uint64_t)'T'<<16)) // 5527630
#define DEFAULT_NXT_DEADLINE 720
#define issue_NXTPOST(cmdstr) bitcoind_RPC(0,"curl",myinfo->NXTAPIURL,0,0,cmdstr)
#define NXT_MSTYPE 5
#define NXT_ASSETTYPE 2
#define NXT_GENESISTIME 1385294400
cJSON *_issue_NXTjson(struct supernet_info *myinfo,char *extra)
{
char cmd[4096],*jsonstr; cJSON *json = 0;
@ -101,6 +101,48 @@ uint32_t get_blockutime(struct supernet_info *myinfo,uint32_t blocknum)
return(timestamp);
}
uint32_t get_NXTheight(struct supernet_info *myinfo,uint32_t *firsttimep)
{
static uint32_t last,lastheight,lastNXTtime;
cJSON *json; uint32_t height = 0; char cmd[256],*jsonstr;
if ( time(NULL) > last+10 )
{
sprintf(cmd,"requestType=getState");
if ( (jsonstr= issue_NXTPOST(cmd)) != 0 )
{
//printf("(%s) -> (%s)\n",cmd,jsonstr);
if ( (json= cJSON_Parse(jsonstr)) != 0 )
{
if ( firsttimep != 0 )
lastNXTtime = *firsttimep = (uint32_t)get_cJSON_int(json,"time");
height = (int32_t)get_cJSON_int(json,"numberOfBlocks");
if ( height > 0 )
height--;
lastheight = height;
free_json(json);
}
free(jsonstr);
}
last = (uint32_t)time(NULL);
}
else
{
height = lastheight;
if ( firsttimep != 0 )
*firsttimep = lastNXTtime;
}
return(height);
}
char *issue_approveTransaction(struct supernet_info *myinfo,char *fullhash,char *revealed,bits256 msghash,char *NXTACCTSECRET)
{
char cmd[4096],secret[8192],str[65];
escape_code(secret,NXTACCTSECRET);
sprintf(cmd,"requestType=approveTransaction&secretPhrase=%s&transactionFullHash=%s&revealedSecret=%s&revealedSecretIsText=false&messageIsText=false&feeNQT=%d&deadline=%d&message=%s",secret,fullhash,revealed,0,DEFAULT_NXT_DEADLINE,bits256_str(str,msghash));
printf("submit approve.(%s)\n",cmd);
return(issue_NXTPOST(cmd));
}
char *MGWassets[][3] =
{
{ "12659653638116877017", "BTC", "8" },
@ -404,6 +446,101 @@ int32_t NXT_assetpolarity(struct supernet_info *myinfo,char *name)
else return(0);
}
uint64_t set_NXTtx(struct supernet_info *myinfo,struct NXT_tx *tx,uint64_t assetidbits,int64_t amount,uint64_t other64bits,int32_t feebits)
{
char assetidstr[64]; int32_t decimals; uint64_t fee = 0; struct NXT_tx U;
memset(&U,0,sizeof(U));
U.senderbits = myinfo->myaddr.nxt64bits;
U.recipientbits = other64bits;
U.assetidbits = assetidbits;
if ( feebits >= 0 )
{
fee = (amount >> feebits);
if ( fee == 0 )
fee = 1;
}
if ( assetidbits != NXT_ASSETID )
{
expand_nxt64bits(assetidstr,assetidbits);
U.type = get_assettype(myinfo,&decimals,assetidstr);
//U.subtype = ap->subtype;
U.U.quantityQNT = amount - fee;
} else U.U.amountNQT = amount - fee;
U.feeNQT = 0;
U.deadline = DEFAULT_NXT_DEADLINE;
printf("set_NXTtx(%llu -> %llu) %.8f of %llu\n",(long long)U.senderbits,(long long)U.recipientbits,dstr(amount),(long long)assetidbits);
*tx = U;
return(fee);
}
cJSON *gen_NXT_tx_json(struct supernet_info *myinfo,char *fullhash,struct NXT_tx *utx,char *reftxid,double myshare)
{
cJSON *json = 0; char secret[8192],cmd[MAX_JSON_FIELD],destNXTaddr[64],assetidstr[64],*retstr;
if ( utx->senderbits == myinfo->myaddr.nxt64bits )
{
expand_nxt64bits(destNXTaddr,utx->recipientbits);
cmd[0] = 0;
if ( utx->type == 0 && utx->subtype == 0 )
sprintf(cmd,"requestType=sendMoney&amountNQT=%lld",(long long)(utx->U.amountNQT*myshare));
else
{
expand_nxt64bits(assetidstr,utx->assetidbits);
if ( utx->type == 2 && utx->subtype == 1 )
sprintf(cmd,"requestType=transferAsset&asset=%s&quantityQNT=%lld",assetidstr,(long long)(utx->U.quantityQNT*myshare));
else if ( utx->type == 5 && utx->subtype == 3 )
sprintf(cmd,"requestType=transferCurrency&currency=%s&units=%lld",assetidstr,(long long)(utx->U.quantityQNT*myshare));
else
{
printf("unsupported type.%d subtype.%d\n",utx->type,utx->subtype);
return(0);
}
}
if ( utx->comment[0] != 0 )
strcat(cmd,"&messageIsText=true&message="),strcat(cmd,utx->comment);
if ( reftxid != 0 && reftxid[0] != 0 && cmd[0] != 0 )
strcat(cmd,"&referencedTransactionFullHash="),strcat(cmd,reftxid);
if ( cmd[0] != 0 )
{
escape_code(secret,myinfo->secret);
sprintf(cmd+strlen(cmd),"&deadline=%u&feeNQT=%lld&secretPhrase=%s&recipient=%s&broadcast=false",utx->deadline,(long long)utx->feeNQT,secret,destNXTaddr);
if ( reftxid != 0 && reftxid[0] != 0 )
sprintf(cmd+strlen(cmd),"&referencedTransactionFullHash=%s",reftxid);
//printf("generated cmd.(%s) reftxid.(%s)\n",cmd,reftxid);
retstr = issue_NXTPOST(cmd);
if ( retstr != 0 )
{
json = cJSON_Parse(retstr);
if ( (json= cJSON_Parse(retstr)) != 0 )
{
if ( jstr(json,"fullHash") != 0 )
strcpy(fullhash,jstr(json,"fullHash"));
// printf("Parsed.(%s)\n",cJSON_Print(json));
}
free(retstr);
}
}
} else printf("cant gen_NXT_txjson when sender.%llu is not me.%llu\n",(long long)utx->senderbits,(long long)myinfo->myaddr.nxt64bits);
return(json);
}
int32_t calc_raw_NXTtx(struct supernet_info *myinfo,char *fullhash,char *utxbytes,char *sighash,uint64_t assetidbits,int64_t amount,uint64_t other64bits)
{
int32_t retval = -1; struct NXT_tx U; cJSON *json;
utxbytes[0] = sighash[0] = 0;
set_NXTtx(myinfo,&U,assetidbits,amount,other64bits,0);
json = gen_NXT_tx_json(myinfo,fullhash,&U,0,1.);
if ( json != 0 )
{
if ( extract_cJSON_str(utxbytes,1024,json,"transactionBytes") > 0 && extract_cJSON_str(sighash,1024,json,"signatureHash") > 0 )
{
retval = 0;
printf("generated utx.(%s) sighash.(%s)\n",utxbytes,sighash);
}
free_json(json);
}
return(retval);
}
#define EXCHANGE_NAME "nxtae"
#define UPDATE nxtae ## _price
#define SUPPORTS nxtae ## _supports
@ -544,7 +681,7 @@ double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchang
return(hbla);
}
uint64_t submit_triggered_nxtae(struct supernet_info *myinfo,int32_t dotrade,char **retjsonstrp,int32_t is_MS,char *bidask,uint64_t assetid,uint64_t qty,uint64_t NXTprice,char *triggerhash,char *comment,uint64_t otherNXT,uint32_t triggerheight)
uint64_t submit_triggered_nxtae(struct supernet_info *myinfo,int32_t dotrade,char **retjsonstrp,int32_t is_MS,char *bidask,uint64_t assetid,uint64_t qty,uint64_t NXTprice,char *triggerhash,char *comment,char *otherNXT,uint32_t triggerheight,char *refhash)
{
int32_t deadline = 1 + 20; uint64_t txid = 0; struct destbuf errstr; char cmd[4096],secret[8192],*jsonstr; cJSON *json;
if ( retjsonstrp != 0 )
@ -564,21 +701,18 @@ uint64_t submit_triggered_nxtae(struct supernet_info *myinfo,int32_t dotrade,cha
}
if ( otherNXT != 0 )
sprintf(cmd+strlen(cmd),"&recipient=%llu",(long long)otherNXT);
if ( refhash != 0 )
sprintf(cmd+strlen(cmd),"&referencedTransactionFullHash=%s",refhash);
if ( triggerhash != 0 && triggerhash[0] != 0 )
{
if ( triggerheight == 0 )
sprintf(cmd+strlen(cmd),"&referencedTransactionFullHash=%s",triggerhash);
else sprintf(cmd+strlen(cmd),"&referencedTransactionFullHash=%s&phased=true&phasingFinishHeight=%u&phasingVotingModel=4&phasingQuorum=1&phasingLinkedFullHash=%s",triggerhash,triggerheight,triggerhash);
}
sprintf(cmd+strlen(cmd),"&phased=true&phasingFinishHeight=%u&phasingVotingModel=4&phasingQuorum=1&phasingLinkedFullHash=%s",triggerheight,triggerhash);
if ( comment != 0 && comment[0] != 0 )
sprintf(cmd+strlen(cmd),"&message=%s",comment);
if ( dotrade == 0 )
{
if ( retjsonstrp != 0 )
{
json = cJSON_CreateObject();
jaddstr(json,"submit",cmd);
*retjsonstrp = jprint(json,1);
strcat(cmd,"&broadcast=false");
*retjsonstrp = issue_NXTPOST(cmd);
}
return(0);
}
@ -603,6 +737,30 @@ uint64_t submit_triggered_nxtae(struct supernet_info *myinfo,int32_t dotrade,cha
return(txid);
}
char *NXT_phasedxfer(struct supernet_info *myinfo,char *othercoin,char *othercoinaddr,char *otherNXT,uint64_t assetid,double volume,char *comment)
{
uint8_t NXT_rmd160[20],addrtype; int32_t is_MS,triggerheight,dotrade = 0;
char onetimecoinaddr[64],triggerhash[41],*cmd,*signedtx = 0; uint64_t ap_mult;
if ( (triggerheight= get_NXTheight(myinfo,0)) != 0 )
{
bitcoin_addr2rmd160(&addrtype,NXT_rmd160,onetimecoinaddr);
init_hexbytes_noT(triggerhash,NXT_rmd160,20);
triggerheight += DEFAULT_NXT_DEADLINE;
if ( (ap_mult= get_assetmult(myinfo,&is_MS,assetid)) == 0 )
return(0);
else
{
if ( assetid == 0 || assetid == NXT_ASSETID )
cmd = "sendMoney";
else if ( is_MS == 0 )
cmd = "transferAsset";
else cmd = "transferCurrency";
submit_triggered_nxtae(myinfo,dotrade,&signedtx,is_MS,cmd,assetid,(volume * SATOSHIDEN) / ap_mult,0,triggerhash,comment,otherNXT,triggerheight,0);
return(signedtx);
}
} else return(0);
}
char *fill_nxtae(struct supernet_info *myinfo,int32_t dotrade,uint64_t *txidp,int32_t dir,double price,double volume,uint64_t baseid,uint64_t relid)
{
uint64_t txid,assetid,avail,qty,priceNQT,ap_mult; int32_t is_MS; char retbuf[512],*errstr,*cmdstr;
@ -617,7 +775,7 @@ char *fill_nxtae(struct supernet_info *myinfo,int32_t dotrade,uint64_t *txidp,in
if ( is_MS == 0 )
cmdstr = dir > 0 ? "placeBidOrder" : "placeAskOrder";
else cmdstr = dir > 0 ? "currencyBuy" : "currencySell";
txid = submit_triggered_nxtae(myinfo,dotrade,&errstr,is_MS,cmdstr,assetid,qty,priceNQT,0,0,0,0);
txid = submit_triggered_nxtae(myinfo,dotrade,&errstr,is_MS,cmdstr,assetid,qty,priceNQT,0,0,0,0,0);
if ( errstr != 0 )
sprintf(retbuf,"{\"error\":\"%s\"}",errstr), free(errstr);
else sprintf(retbuf,"{\"result\":\"success\",\"txid\":\"%llu\"}",(long long)txid);

12
iguana/iguana777.h

@ -470,10 +470,10 @@ struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],r
struct vin_info
{
struct iguana_msgvin vin;
int32_t M,N,validmask,spendlen,type;
int32_t M,N,validmask,spendlen,type,p2shlen;
struct vin_signer signers[16];
char coinaddr[65];
uint8_t rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE];
uint8_t rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE],p2shscript[IGUANA_MAXSCRIPTSIZE];
};
// peers
@ -588,7 +588,7 @@ double dxblend(double *destp,double val,double decay);
// json
int32_t iguana_processjsonQ(struct iguana_info *coin); // reentrant, can be called during any idletime
char *iguana_JSON(char *jsonstr);
char *iguana_JSON(char *);
char *SuperNET_p2p(struct iguana_info *coin,struct iguana_peer *addr,int32_t *delaymillisp,char *ipaddr,uint8_t *data,int32_t datalen,int32_t compressed);
char *mbstr(char *str,double);
@ -682,7 +682,7 @@ void iguana_bundleiclear(struct iguana_info *coin,struct iguana_bundle *bp,int32
int32_t hcalc_bitsize(uint64_t x);
struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_pkhash *p,uint8_t rmd160[20]);
struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,struct iguana_txid *tx,bits256 txid);
int32_t iguana_scriptgen(struct iguana_info *coin,char *coinaddr,uint8_t *script,char *asmstr,uint8_t rmd160[20],uint8_t type,int32_t txi,struct vin_info *vp);
int32_t iguana_scriptgen(struct iguana_info *coin,int32_t *Mp,int32_t *nump,char *coinaddr,uint8_t *script,char *asmstr,uint8_t rmd160[20],uint8_t type,const struct vin_info *vp,int32_t txi);
int32_t iguana_ramchain_spendtxid(struct iguana_info *coin,bits256 *txidp,struct iguana_txid *T,int32_t numtxids,bits256 *X,int32_t numexternaltxids,struct iguana_spend *s);
struct iguana_info *iguana_coinselect();
void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr);
@ -728,9 +728,9 @@ int32_t category_peer(struct supernet_info *myinfo,struct iguana_peer *addr,bits
int32_t btc_wif2priv(uint8_t *addrtypep,uint8_t privkey[32],char *wifstr);
bits256 iguana_chaingenesis(int32_t version,uint32_t timestamp,uint32_t nBits,uint32_t nonce,bits256 merkle_root);
int32_t iguana_send_ConnectTo(struct iguana_info *coin,struct iguana_peer *addr);
cJSON *iguana_txjson(struct iguana_info *coin,struct iguana_txid *tx,int32_t height);
cJSON *iguana_txjson(struct iguana_info *coin,struct iguana_txid *tx,int32_t height,struct vin_info *V);
char *iguana_txscan(struct iguana_info *coin,cJSON *json,uint8_t *data,int32_t recvlen,bits256 txid);
char *iguana_rawtxbytes(struct iguana_info *coin,uint8_t *serialized,int32_t datalen,cJSON *json,struct iguana_msgtx *msgtx);
char *iguana_rawtxbytes(struct iguana_info *coin,cJSON *json,struct iguana_msgtx *msgtx);
int32_t iguana_send_VPNversion(struct iguana_info *coin,struct iguana_peer *addr,uint64_t myservices);
void exchanges777_init(struct supernet_info *myinfo,cJSON *exchanges,int32_t sleepflag);
int32_t iguana_rwvout(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgvout *msg);

196
iguana/iguana_instantdex.c

@ -20,19 +20,28 @@
#define INSTANTDEX_HOPS 3
#define INSTANTDEX_DURATION 60
#define INSTANTDEX_PROPOSE 1
#define INSTANTDEX_ACCEPT 2
#define INSTANTDEX_CONFIRM 3
#define INSTANTDEX_NXTOFFER 1
#define INSTANTDEX_REQUEST 2
#define INSTANTDEX_PROPOSE 3
#define INSTANTDEX_ACCEPT 4
#define INSTANTDEX_CONFIRM 5
cJSON *InstantDEX_argjson(char *reference,char *message,bits256 basetxid,bits256 reltxid,int32_t iter,int32_t val,int32_t val2)
struct instantdex_entry { char base[24],rel[24]; double price,volume,pendingvolume; uint32_t expiration,nonce; };
struct instantdex_accept { struct queueitem DL; uint64_t txid; struct instantdex_entry A; };
cJSON *InstantDEX_argjson(char *reference,char *message,char *othercoinaddr,char *otherNXTaddr,int32_t iter,int32_t val,int32_t val2)
{
cJSON *argjson = cJSON_CreateObject();
if ( reference != 0 )
jaddstr(argjson,"refstr",reference);
if ( message != 0 && message[0] != 0 )
jaddstr(argjson,"message",message);
jaddbits256(argjson,"basetxid",basetxid);
jaddbits256(argjson,"reltxid",reltxid);
if ( othercoinaddr != 0 && othercoinaddr[0] != 0 )
jaddstr(argjson,"othercoinaddr",othercoinaddr);
if ( otherNXTaddr != 0 && otherNXTaddr[0] != 0 )
jaddstr(argjson,"otherNXTaddr",otherNXTaddr);
//jaddbits256(argjson,"basetxid",basetxid);
//jaddbits256(argjson,"reltxid",reltxid);
if ( iter != 3 )
{
if ( val == 0 )
@ -204,11 +213,56 @@ double instantdex_aveprice(struct supernet_info *myinfo,struct exchange_quote *s
return(0);
}
char *instantdex_request(struct supernet_info *myinfo,char *cmdstr,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen)
cJSON *instantdex_acceptjson(struct instantdex_accept *ap)
{
cJSON *item = cJSON_CreateObject();
jadd64bits(item,"orderid",ap->txid);
jaddstr(item,"base",ap->A.base);
jaddstr(item,"rel",ap->A.rel);
jaddnum(item,"price",ap->A.price);
jaddnum(item,"volume",ap->A.volume);
jaddnum(item,"pendingvolume",ap->A.pendingvolume);
jaddnum(item,"expiresin",ap->A.expiration - time(NULL));
return(item);
}
double instantdex_acceptable(struct supernet_info *myinfo,cJSON *array,char *refstr,char *base,char *rel,double volume)
{
struct instantdex_accept PAD,*ap,*retap = 0; double price = 0.; uint32_t now;
now = (uint32_t)time(NULL);
memset(&PAD,0,sizeof(PAD));
queue_enqueue("acceptableQ",&myinfo->acceptableQ,&PAD.DL,0);
while ( (ap= queue_dequeue(&myinfo->acceptableQ,0)) != 0 && ap != &PAD )
{
if ( volume > 0. && (strcmp(base,"*") == 0 || strcmp(base,ap->A.base) == 0) && (strcmp(rel,"*") == 0 || strcmp(rel,ap->A.rel) == 0) && volume < (ap->A.volume - ap->A.pendingvolume) )
{
if ( ap->A.price > price )
{
price = ap->A.price;
retap = ap;
}
}
if ( now < ap->A.expiration )
{
if ( array != 0 )
jaddi(array,instantdex_acceptjson(ap));
queue_enqueue("acceptableQ",&myinfo->acceptableQ,&ap->DL,0);
}
}
if ( retap != 0 )
{
retap->A.pendingvolume -= volume;
price = retap->A.price;
}
return(price);
}
char *instantdex_request(struct supernet_info *myinfo,char *cmdstr,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen) // receiving side
{
char *base,*rel,*request,*refstr,*nextcmdstr,*message,*traderip;
double volume,price,aveprice,totalvol; cJSON *newjson; int32_t duration,flags,nextcmd;
int32_t num,depth; struct exchange_quote sortbuf[1000]; bits256 basetxid,reltxid;
struct NXT_tx feeT; char fullhash[256],*othercoinaddr; cJSON *feejson; uint64_t assetbits = 0;
char *base,*rel,*request,*refstr,*nextcmdstr,*message,*traderip,*otherNXTaddr;
double volume,price; cJSON *newjson; int32_t duration,flags,nextcmd;
int32_t num,depth; //struct exchange_quote sortbuf[1000]; bits256 basetxid,reltxid;,aveprice,totalvol
if ( argjson != 0 )
{
num = 0;
@ -227,40 +281,73 @@ char *instantdex_request(struct supernet_info *myinfo,char *cmdstr,struct instan
printf("got my own request\n");
return(clonestr("{\"result\":\"got my own request\"}"));
}
if ( strcmp(cmdstr,"request") == 0 )
// NXToffer:
// sends NXT assetid, volume and desired rel, also reftx
if ( strcmp(cmdstr,"NXToffer") == 0 )
{
aveprice = instantdex_aveprice(myinfo,sortbuf,(int32_t)(sizeof(sortbuf)/sizeof(*sortbuf)),&totalvol,base,rel,volume,argjson);
OS_randombytes(basetxid.bytes,sizeof(basetxid));
OS_randombytes(reltxid.bytes,sizeof(reltxid));
char str[65]; printf("GENERATE txid.%s aveprice %.8f vol %f\n",bits256_str(str,basetxid),aveprice,totalvol);
nextcmd = INSTANTDEX_PROPOSE;
nextcmdstr = "proposal";
message = "hello";
price = aveprice;
volume = totalvol;
if ( (price= instantdex_acceptable(myinfo,0,refstr,base,rel,volume)) > 0. )
{
// sends NXT assetid, volume and desired
if ( strcmp(base,"NXT") == 0 || strcmp(base,"nxt") == 0 )
assetbits = NXT_ASSETID;
else if ( is_decimalstr(base) > 0 )
assetbits = calc_nxt64bits(base);
if ( assetbits != 0 )
{
nextcmd = INSTANTDEX_REQUEST;
nextcmdstr = "request";
}
}
}
else if ( strcmp(cmdstr,"request") == 0 )
{
// request:
// other node sends (othercoin, othercoinaddr, otherNXT and reftx that expires before phasedtx)
if ( (strcmp(rel,"BTC") == 0 || strcmp(base,"BTC") == 0) && (price= instantdex_acceptable(myinfo,0,refstr,base,rel,volume)) > 0. )
{
//aveprice = instantdex_aveprice(myinfo,sortbuf,(int32_t)(sizeof(sortbuf)/sizeof(*sortbuf)),&totalvol,base,rel,volume,argjson);
set_NXTtx(myinfo,&feeT,assetbits,SATOSHIDEN*3,calc_nxt64bits(INSTANTDEX_ACCT),-1);
if ( (feejson= gen_NXT_tx_json(myinfo,fullhash,&feeT,0,1.)) != 0 )
free_json(feejson);
nextcmd = INSTANTDEX_PROPOSE;
nextcmdstr = "proposal";
othercoinaddr = myinfo->myaddr.BTC;
otherNXTaddr = myinfo->myaddr.NXTADDR;
}
}
else
{
basetxid = jbits256(argjson,"basetxid");
reltxid = jbits256(argjson,"reltxid");
if ( strcmp(cmdstr,"proposal") == 0 )
{
// proposal:
// NXT node submits phasedtx that refers to it, but it wont confirm
nextcmd = INSTANTDEX_ACCEPT;
nextcmdstr = "accept";
message = "world";
message = "";
//instantdex_phasetxsubmit(refstr);
}
else if ( strcmp(cmdstr,"accept") == 0 )
{
// accept:
// other node verifies unconfirmed has phasedtx and broadcasts cltv, also to NXT node, releases trigger
nextcmd = INSTANTDEX_CONFIRM;
nextcmdstr = "confirm";
message = "confirmed";
message = "";
//instantdex_phasedtxverify();
//instantdex_cltvbroadcast();
//instantdex_releasetrigger();
}
else if ( strcmp(cmdstr,"confirm") == 0 )
{
// confirm:
// NXT node verifies bitcoin txbytes has proper payment and cashes in with onetimepubkey
// BTC* node approves phased tx with onetimepubkey
//instantdex_cltvverify();
//instantdex_phasetxapprove();
return(clonestr("{\"error\":\"trade confirmed\"}"));
}
}
if ( (newjson= InstantDEX_argjson(refstr,message,basetxid,reltxid,nextcmd,duration,flags)) != 0 )
if ( nextcmd != 0 && (newjson= InstantDEX_argjson(refstr,message,othercoinaddr,otherNXTaddr,nextcmd,duration,flags)) != 0 )
{
jaddnum(newjson,"price",price);
jaddnum(newjson,"volume",volume);
@ -274,8 +361,10 @@ char *instantdex_parse(struct supernet_info *myinfo,struct instantdex_msghdr *ms
{
static struct { char *cmdstr; char *(*func)(struct supernet_info *myinfo,char *cmdstr,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen); uint64_t cmdbits; } cmds[] =
{
{ "request", instantdex_request }, { "proposal", instantdex_request },
{ "accept", instantdex_request }, { "confirm", instantdex_request },
{ "NXToffer", instantdex_request }, { "request", instantdex_request },
{ "proposal", instantdex_request },
{ "accept", instantdex_request },
{ "confirm", instantdex_request },
};
char *retstr = 0; int32_t i; uint64_t cmdbits;
if ( cmds[0].cmdbits == 0 )
@ -345,7 +434,34 @@ char *InstantDEX_hexmsg(struct supernet_info *myinfo,void *ptr,int32_t len,char
#include "../includes/iguana_apidefs.h"
THREE_STRINGS_AND_DOUBLE(InstantDEX,request,reference,base,rel,volume)
// NXTrequest:
// sends NXT assetid, volume and desired
// request:
// other node sends (othercoin, othercoinaddr, otherNXT and reftx that expires well before phasedtx)
// proposal:
// NXT node submits phasedtx that refers to it, but it wont confirm
// approve:
// other node verifies unconfirmed has phasedtx and broadcasts cltv, also to NXT node, releases trigger
// confirm:
// NXT node verifies bitcoin txbytes has proper payment and cashes in with onetimepubkey
// BTC* node approves phased tx with onetimepubkey
TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,acceptable,base,rel,price,volume)
{
struct instantdex_accept A; bits256 hash;
memset(&A,0,sizeof(A));
OS_randombytes((uint8_t *)&A.A.nonce,sizeof(A.A.nonce));
safecopy(A.A.base,base,sizeof(A.A.base));
safecopy(A.A.rel,rel,sizeof(A.A.rel));
A.A.price = price, A.A.volume = volume;
A.A.expiration = (uint32_t)time(NULL) + 3600;
vcalc_sha256(0,hash.bytes,(void *)&A.A,sizeof(A.A));
A.txid = hash.txid;
queue_enqueue("acceptableQ",&myinfo->acceptableQ,&A.DL,0);
return(clonestr("{\"result\":\"added acceptable\"}"));
}
THREE_STRINGS_AND_DOUBLE(InstantDEX,NXToffer,reference,base,rel,volume) // initiator
{
int32_t hops = INSTANTDEX_HOPS; cJSON *argjson;
if ( remoteaddr == 0 )
@ -355,21 +471,35 @@ THREE_STRINGS_AND_DOUBLE(InstantDEX,request,reference,base,rel,volume)
jaddstr(argjson,"base",base);
jaddstr(argjson,"rel",rel);
jaddnum(argjson,"volume",volume);
return(instantdex_sendcmd(myinfo,argjson,"request",myinfo->ipaddr,hops));
return(instantdex_sendcmd(myinfo,argjson,"NXToffer",myinfo->ipaddr,hops));
} else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}"));
}
TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,proposal,reference,message,basetxid,reltxid,duration,flags)
THREE_STRINGS_AND_DOUBLE(InstantDEX,request,reference,base,rel,volume) // initiator
{
int32_t hops = INSTANTDEX_HOPS; cJSON *argjson;
if ( remoteaddr == 0 )
{
argjson = InstantDEX_argjson(reference,message,basetxid,reltxid,INSTANTDEX_PROPOSE,duration,flags);
argjson = cJSON_CreateObject();
jaddstr(argjson,"refstr",reference);
jaddstr(argjson,"base",base);
jaddstr(argjson,"rel",rel);
jaddnum(argjson,"volume",volume);
return(instantdex_sendcmd(myinfo,argjson,"request",myinfo->ipaddr,hops));
} else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}"));
}
TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,proposal,reference,message,basetxid,reltxid,duration,flags) // responder
{
int32_t hops = INSTANTDEX_HOPS; cJSON *argjson; char str[65],str2[65];
if ( remoteaddr == 0 )
{
argjson = InstantDEX_argjson(reference,message,bits256_str(str,basetxid),bits256_str(str2,basetxid),INSTANTDEX_PROPOSE,duration,flags);
return(instantdex_sendcmd(myinfo,argjson,"proposal",myinfo->ipaddr,hops));
} else return(clonestr("{\"error\":\"InstantDEX API proposal only local usage!\"}"));
}
TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,accept,reference,message,basetxid,reltxid,duration,flags)
/*TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,accept,reference,message,basetxid,reltxid,duration,flags)
{
int32_t hops = INSTANTDEX_HOPS; cJSON *argjson;
if ( remoteaddr == 0 )
@ -387,7 +517,7 @@ TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,confirm,reference,message,basetx
argjson = InstantDEX_argjson(reference,message,basetxid,reltxid,INSTANTDEX_CONFIRM,baseheight,relheight);
return(instantdex_sendcmd(myinfo,argjson,"confirm",myinfo->ipaddr,hops));
} else return(clonestr("{\"error\":\"InstantDEX API confirm only local usage!\"}"));
}
}*/
#include "../includes/iguana_apiundefs.h"

4
iguana/iguana_json.c

@ -89,6 +89,7 @@ cJSON *SuperNET_helpjson()
#define IGUANA_HELP_SSH(agent,name,str,str2,hash) array = helpjson(IGUANA_ARGS,#agent,#name,helparray3(cJSON_CreateArray(),helpitem(#str,"string"),helpitem(#str2,"string"),helpitem(#hash,"hash")))
#define IGUANA_HELP_SSHI(agent,name,str,str2,hash,val) array = helpjson(IGUANA_ARGS,#agent,#name,helparray4(cJSON_CreateArray(),helpitem(#str,"string"),helpitem(#str2,"string"),helpitem(#hash,"hash"),helpitem(#val,"int")))
#define IGUANA_HELP_SSDD(agent,name,str,str2,val,val2) array = helpjson(IGUANA_ARGS,#agent,#name,helparray4(cJSON_CreateArray(),helpitem(#str,"string"),helpitem(#str2,"string"),helpitem(#val,"float"),helpitem(#val2,"float")))
#define IGUANA_HELP_SSHII(agent,name,str,str2,hash,val,val2) array = helpjson(IGUANA_ARGS,#agent,#name,helparray5(cJSON_CreateArray(),helpitem(#str,"string"),helpitem(#str2,"string"),helpitem(#hash,"hash"),helpitem(#val,"int"),helpitem(#val2,"int")))
#define IGUANA_HELP_SSHHII(agent,name,str,str2,hash,hash2,val,val2) array = helpjson(IGUANA_ARGS,#agent,#name,helparray6(cJSON_CreateArray(),helpitem(#str,"string"),helpitem(#str2,"string"),helpitem(#hash,"hash"),helpitem(#hash2,"hash"),helpitem(#val,"int"),helpitem(#val2,"int")))
#define IGUANA_HELP_SI(agent,name,str,val) array = helpjson(IGUANA_ARGS,#agent,#name,helparray2(cJSON_CreateArray(),helpitem(#str,"string"),helpitem(#val,"int")))
@ -164,6 +165,7 @@ cJSON *SuperNET_helpjson()
#define THREE_STRINGS_AND_THREE_DOUBLES IGUANA_HELP_SSSDDD
#define THREE_STRINGS_AND_DOUBLE IGUANA_HELP_SSSD
#define STRING_AND_DOUBLE IGUANA_HELP_SD
#define TWO_STRINGS_AND_TWO_DOUBLES IGUANA_HELP_SSDD
#include "../includes/iguana_apideclares.h"
@ -840,6 +842,7 @@ char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,c
#define IGUANA_DISPATCH_SSS(agent,name,str,str2,str3) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jstr(json,#str2),jstr(json,#str3)))
#define IGUANA_DISPATCH_SSSS(agent,name,str,str2,str3,str4) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jstr(json,#str2),jstr(json,#str3),jstr(json,#str4)))
#define IGUANA_DISPATCH_SSSD(agent,name,str,str2,str3,amount) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jstr(json,#str2),jstr(json,#str3),jdouble(json,#amount)))
#define IGUANA_DISPATCH_SSDD(agent,name,str,str2,val,val2) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jstr(json,#str2),jdouble(json,#val),jdouble(json,#val2)))
#define IGUANA_DISPATCH_SSSDDD(agent,name,str,str2,str3,val,val2,val3) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jstr(json,#str2),jstr(json,#str3),jdouble(json,#val),jdouble(json,#val2),jdouble(json,#val3)))
#define IGUANA_DISPATCH_SSSIII(agent,name,str,str2,str3,val,val2,val3) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jstr(json,#str2),jstr(json,#str3),jint(json,#val),jint(json,#val2),jint(json,#val3)))
@ -920,6 +923,7 @@ char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,c
#define THREE_STRINGS_AND_THREE_DOUBLES IGUANA_DISPATCH_SSSDDD
#define THREE_STRINGS_AND_DOUBLE IGUANA_DISPATCH_SSSD
#define STRING_AND_DOUBLE IGUANA_DISPATCH_SD
#define TWO_STRINGS_AND_TWO_DOUBLES IGUANA_DISPATCH_SSDD
#include "../includes/iguana_apideclares.h"
//#undef IGUANA_ARGS

5
iguana/iguana_pubkeys.c

@ -345,7 +345,10 @@ cstring *base58_decode_check(uint8_t *addrtype,const char *s_in)
}
else
{
char str[65]; printf("checkhash mismatch %02x %02x %02x %02x vs %02x %02x %02x %02x (%s)\n",s->str[s->len - 4]&0xff,s->str[s->len - 3]&0xff,s->str[s->len - 2]&0xff,s->str[s->len - 1]&0xff,hash.bytes[31],hash.bytes[30],hash.bytes[29],hash.bytes[28],bits256_str(str,hash));
int32_t i;
for (i=0; i<s->len; i++)
printf("%02x ",s->str[i]&0xff);
char str[65]; printf(" s->len.%ld\n>>>>>>>> matched %02x %02x %02x %02x vs %02x %02x %02x %02x (%s) (%s)\n",s->len,s->str[s->len - 4]&0xff,s->str[s->len - 3]&0xff,s->str[s->len - 2]&0xff,s->str[s->len - 1]&0xff,hash.bytes[31],hash.bytes[30],hash.bytes[29],hash.bytes[28],bits256_str(str,hash),s_in);
}
}
cstr_free(s,true);

2
iguana/iguana_tx.c

@ -58,7 +58,7 @@ int32_t iguana_voutset(struct iguana_info *coin,uint8_t *scriptspace,char *asmst
vout->value = u->value;
vout->pk_script = scriptspace;
memset(&V,0,sizeof(V));
scriptlen = iguana_scriptgen(coin,coinaddr,scriptspace,asmstr,p->rmd160,u->type,i,&V);
scriptlen = iguana_scriptgen(coin,&V.M,&V.N,coinaddr,scriptspace,asmstr,p->rmd160,u->type,(const struct vin_info *)&V,i);
}
vout->pk_scriptlen = scriptlen;
return(scriptlen);

2
iguana/main.c

@ -346,7 +346,7 @@ void iguana_main(void *arg)
category_init(&MYINFO);
if ( (coinargs= SuperNET_keysinit(&MYINFO,arg)) != 0 )
iguana_launch(iguana_coinadd("BTCD"),"iguana_coins",iguana_coins,coinargs,IGUANA_PERMTHREAD);
else if ( 0 )
else if ( 1 )
{
#ifdef __APPLE__
sleep(1);

6
includes/iguana_apideclares.h

@ -44,10 +44,12 @@ STRING_AND_INT(InstantDEX,pollgap,exchange,pollgap);
ZERO_ARGS(InstantDEX,allexchanges);
STRING_ARG(InstantDEX,allpairs,exchange);
TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,acceptable,base,rel,price,volume);
THREE_STRINGS_AND_DOUBLE(InstantDEX,NXToffer,reference,base,rel,volume);
THREE_STRINGS_AND_DOUBLE(InstantDEX,request,reference,base,rel,volume);
TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,proposal,reference,message,basetxid,reltxid,duration,flags);
TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,accept,reference,message,basetxid,reltxid,duration,flags);
TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,confirm,reference,message,basetxid,reltxid,baseheight,relheight);
//TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,accept,reference,message,basetxid,reltxid,duration,flags);
//TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,confirm,reference,message,basetxid,reltxid,baseheight,relheight);
THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission);
STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission);

2
includes/iguana_apidefs.h

@ -22,6 +22,7 @@
#define IGUANA_CFUNC_SSI(agent,name,str,str2,val) char *agent ## _ ## name(IGUANA_ARGS,char *str,char *str2,int32_t val)
#define IGUANA_CFUNC_SSH(agent,name,str,str2,hash) char *agent ## _ ## name(IGUANA_ARGS,char *str,char *str2,bits256 hash)
#define IGUANA_CFUNC_SSHI(agent,name,str,str2,hash,val) char *agent ## _ ## name(IGUANA_ARGS,char *str,char *str2,bits256 hash,int32_t val)
#define IGUANA_CFUNC_SSDD(agent,name,str,str2,val,val2) char *agent ## _ ## name(IGUANA_ARGS,char *str,char *str2,double val,double val2)
#define IGUANA_CFUNC_SSHII(agent,name,str,str2,hash,val,val2) char *agent ## _ ## name(IGUANA_ARGS,char *str,char *str2,bits256 hash,int32_t val,int32_t val2)
#define IGUANA_CFUNC_SSHHII(agent,name,str,str2,hash,hash2,val,val2) char *agent ## _ ## name(IGUANA_ARGS,char *str,char *str2,bits256 hash,bits256 hash2,int32_t val,int32_t val2)
#define IGUANA_CFUNC_SSS(agent,name,str,str2,str3) char *agent ## _ ## name(IGUANA_ARGS,char *str,char *str2,char *str3)
@ -86,3 +87,4 @@
#define THREE_STRINGS_AND_THREE_INTS IGUANA_CFUNC_SSSIII
#define THREE_STRINGS_AND_THREE_DOUBLES IGUANA_CFUNC_SSSDDD
#define THREE_STRINGS_AND_DOUBLE IGUANA_CFUNC_SSSD
#define TWO_STRINGS_AND_TWO_DOUBLES IGUANA_CFUNC_SSDD

1
includes/iguana_apiundefs.h

@ -38,6 +38,7 @@
#undef THREE_STRINGS_AND_DOUBLE
#undef STRING_AND_DOUBLE
#undef FOUR_STRINGS
#undef TWO_STRINGS_AND_TWO_DOUBLES
#undef IGUANA_ARGS
#undef IGUANA_CALLARGS

Loading…
Cancel
Save