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. 8
      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 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 CHROME_ARGS += --allow-nacl-socket-api=127.0.0.1
DEPS = nacl_io DEPS = nacl_io

101
deprecated/obsolete.h

@ -13091,5 +13091,106 @@ len = 0;
} }
return(clonestr("{\"error\":\"need pubkey\"}")); 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 #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 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 iguana.sources
include ../crypto777/crypto777.sources include ../crypto777/crypto777.sources
@ -21,7 +22,9 @@ CHROME_ARGS += --allow-nacl-socket-api=127.0.0.1
DEPS = nacl_io DEPS = nacl_io
#LIBS = curl ssl crypto z glibc-compat nacl_spawn ppapi nacl_io ppapi_cpp ppapi_simple # cli_main #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) CFLAGS = -Wall -O2 -fno-strict-aliasing $(EXTRA)
LFLAGS = libs LFLAGS = libs

20
iguana/SuperNET.h

@ -84,10 +84,27 @@ struct supernet_info
int32_t LBsock,PUBsock,reqsock,subsock,networktimeout,maxdelay; int32_t LBsock,PUBsock,reqsock,subsock,networktimeout,maxdelay;
uint16_t LBport,PUBport,reqport,subport; uint16_t LBport,PUBport,reqport,subport;
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; int32_t numagents,numexchanges; struct supernet_agent agents[SUPERNET_MAXAGENTS]; queue_t acceptQ,acceptableQ;
int32_t numagents,numexchanges;
struct exchange_info *tradingexchanges[SUPERNET_MAXEXCHANGES]; struct exchange_info *tradingexchanges[SUPERNET_MAXEXCHANGES];
char handle[1024]; 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 /*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); 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); 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 #endif

648
iguana/exchanges/bitcoin.c

@ -31,6 +31,15 @@ static const char base58_chars[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijk
#define IGUANA_SCRIPT_DATA 11 #define IGUANA_SCRIPT_DATA 11
#define IGUANA_SCRIPT_STRANGE 15 #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) 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; 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; be_sz = (uint32_t)len + (uint32_t)zeroes;
memset(data,0,be_sz); memset(data,0,be_sz);
for (i=0; i<len; i++) 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: out:
BN_clear_free(&bn58), BN_clear_free(&bn), BN_clear_free(&bnChar); BN_clear_free(&bn58), BN_clear_free(&bn), BN_clear_free(&bnChar);
BN_CTX_free(ctx); BN_CTX_free(ctx);
@ -146,23 +156,29 @@ out:
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)
{ {
bits256 hash; uint8_t buf[25]; int32_t len; bits256 hash; uint8_t *buf,_buf[25]; int32_t len;
memset(rmd160,0,20); memset(rmd160,0,20);
*addrtypep = 0; *addrtypep = 0;
buf = _buf;
if ( (len= bitcoin_base58decode(buf,coinaddr)) >= 4 ) if ( (len= bitcoin_base58decode(buf,coinaddr)) >= 4 )
{ {
// validate with trailing hash, then remove hash // validate with trailing hash, then remove hash
hash = bits256_doublesha256(0,buf,len - 4); 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] ) 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]; //printf("coinaddr.(%s) valid checksum\n",coinaddr);
memcpy(rmd160,buf+1,20);
return(20);
} }
else 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); 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) 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]; int32_t i; uint8_t data[25]; bits256 hash; char checkaddr[65];
vcalc_sha256(0,hash.bytes,pubkey,len); if ( len != 20 )
calc_rmd160(0,data+1,hash.bytes,sizeof(hash)); {
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); btc_convrmd160(checkaddr,addrtype,data+1);
for (i=0; i<20; i++) //for (i=0; i<20; i++)
printf("%02x",data[i+1]); // printf("%02x",data[i+1]);
printf(" RMD160 len.%d\n",len); //printf(" RMD160 len.%d\n",len);
data[0] = addrtype; data[0] = addrtype;
hash = bits256_doublesha256(0,data,21); hash = bits256_doublesha256(0,data,21);
for (i=0; i<4; i++) 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]; uint8_t checktype,rmd160[20];
bitcoin_addr2rmd160(&checktype,rmd160,coinaddr); 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); 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]) 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; script[n++] = SCRIPT_OP_CHECKSIG;
return(n); return(n);
} }
@ -319,54 +342,84 @@ int32_t bitcoin_checklocktimeverify(uint8_t *script,int32_t n,uint32_t locktime)
return(n); return(n);
} }
int32_t bitcoin_pubkeylen(uint8_t *pubkey) int32_t bitcoin_MofNspendscript(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,const struct vin_info *vp)
{
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)
{ {
uint8_t sha256[32]; int32_t i,plen; uint8_t sha256[32]; int32_t i,plen;
script[n++] = 0x50 + M; script[n++] = 0x50 + vp->M;
for (i=0; i<N; i++) for (i=0; i<vp->N; i++)
{ {
if ( (plen= bitcoin_pubkeylen(vp->signers[i].pubkey)) < 0 ) if ( (plen= bitcoin_pubkeylen(vp->signers[i].pubkey)) < 0 )
return(-1); return(-1);
memcpy(&script[n],vp->signers[i].pubkey,plen); memcpy(&script[n],vp->signers[i].pubkey,plen);
n += plen; n += plen;
} }
script[n++] = 0x50 + N; script[n++] = 0x50 + vp->N;
script[n++] = SCRIPT_OP_CHECKMULTISIG; script[n++] = SCRIPT_OP_CHECKMULTISIG;
vcalc_sha256(0,sha256,script,n); vcalc_sha256(0,sha256,script,n);
calc_rmd160(0,p2sh_rmd160,sha256,sizeof(sha256)); calc_rmd160(0,p2sh_rmd160,sha256,sizeof(sha256));
return(n); 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 // OP_IF
// <timestamp> OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 <hash160> OP_EQUALVERIFY OP_CHECKSIG // <timestamp> OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 <hash160> OP_EQUALVERIFY OP_CHECKSIG
// OP_ELSE // OP_ELSE
// OP_DUP OP_HASH160 <hash160> OP_EQUALVERIFY OP_CHECKSIG // standard spend // OP_DUP OP_HASH160 <hash160> OP_EQUALVERIFY OP_CHECKSIG // standard spend
// OP_ENDIF // OP_ENDIF
uint8_t hex[4096]; int32_t n = 0; uint8_t sha256[32],rmd160A[20],rmd160B[20],addrtypeA,addrtypeB;
hex[n++] = SCRIPT_OP_IF; bitcoin_addr2rmd160(&addrtypeA,rmd160A,senderaddr);
n = bitcoin_checklocktimeverify(hex,n,locktime); bitcoin_addr2rmd160(&addrtypeB,rmd160B,destaddr);
n = bitcoin_standardspend(hex,n,rmd160A); script[n++] = SCRIPT_OP_IF;
hex[n++] = SCRIPT_OP_ELSE; n = bitcoin_checklocktimeverify(script,n,locktime);
n = bitcoin_standardspend(hex,n,rmd160B); n = bitcoin_standardspend(script,n,rmd160A);
hex[n++] = SCRIPT_OP_ENDIF; script[n++] = SCRIPT_OP_ELSE;
init_hexbytes_noT(scriptstr,hex,n); n = bitcoin_standardspend(script,n,rmd160B);
return(scriptstr); 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; m = n = 1;
if ( type == IGUANA_SCRIPT_76A988AC || type == IGUANA_SCRIPT_76AC || type == IGUANA_SCRIPT_P2SH ) 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); init_hexbytes_noT(rmd160str,rmd160,20);
btc_convrmd160(coinaddr,addrtype,rmd160); btc_convrmd160(coinaddr,addrtype,rmd160);
} }
//printf("addrtype.%d\n",addrtype);
switch ( type ) switch ( type )
{ {
case IGUANA_SCRIPT_NULL: case IGUANA_SCRIPT_NULL:
@ -385,8 +437,10 @@ int32_t iguana_scriptgen(struct iguana_info *coin,char *coinaddr,uint8_t *script
coinaddr[0] = 0; coinaddr[0] = 0;
break; break;
case IGUANA_SCRIPT_76AC: case IGUANA_SCRIPT_76AC:
sprintf(asmstr,"OP_DUP %s OP_CHECKSIG // %s",rmd160str,coinaddr); init_hexbytes_noT(pubkeystr,(uint8_t *)vp->signers[0].pubkey,bitcoin_pubkeylen(vp->signers[0].pubkey));
scriptlen = bitcoin_pubkeyspend(script,0,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; break;
case IGUANA_SCRIPT_76A988AC: case IGUANA_SCRIPT_76A988AC:
sprintf(asmstr,"OP_DUP OP_HASH160 %s OP_EQUALVERIFY OP_CHECKSIG // %s",rmd160str,coinaddr); 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 ) if ( n > 1 )
{ {
scriptlen = bitcoin_MofN(rmd160,script,0,vp,m,n); scriptlen = bitcoin_MofNspendscript(rmd160,script,0,vp);
sprintf(asmstr,"%d ",m); sprintf(asmstr,"%d ",m);
for (i=0; i<n; i++) 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," "); strcat(asmstr," ");
} }
sprintf(asmstr + strlen(asmstr),"%d // M.%d of N.%d [",n,m,n); 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"); strcat(asmstr,"]\n");
} }
if ( flag != 0 && vp->spendlen > 0 ) if ( flag != 0 && vp->spendlen > 0 )
init_hexbytes_noT(asmstr + strlen(asmstr),vp->spendscript,vp->spendlen); init_hexbytes_noT(asmstr + strlen(asmstr),(uint8_t *)vp->spendscript,vp->spendlen);
return(0); *Mp = m, *nump = n;
return(scriptlen);
} }
int32_t _iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp) 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); 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 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]; 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->spendlen = pk_scriptlen;
vp->vin.sequence = sequence; vp->vin.sequence = sequence;
memcpy(vp->spendscript,pk_script,pk_scriptlen); 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 ) 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 ) 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); 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_hash = jbits256(vinobj,"txid");
vin->prev_vout = jint(vinobj,"vout"); vin->prev_vout = jint(vinobj,"vout");
if ( (sigjson= jobj(vinobj,"scriptSig")) != 0 ) if ( (sigjson= jobj(vinobj,"scriptSig")) != 0 )
hexstr = jstr(sigjson,"redeemScript"); hexstr = jstr(sigjson,"hex");
} }
if ( hexstr != 0 ) if ( hexstr != 0 )
{ {
@ -631,46 +672,42 @@ int32_t iguana_parsevinobj(struct iguana_info *coin,uint8_t *serialized,int32_t
return(len); 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) cJSON *iguana_voutjson(struct iguana_info *coin,struct iguana_msgvout *vout,int32_t txi,bits256 txid)
{ {
// 035f1321ed17d387e4433b2fa229c53616057964af065f98bfcae2233c5108055e OP_CHECKSIG // 035f1321ed17d387e4433b2fa229c53616057964af065f98bfcae2233c5108055e OP_CHECKSIG
char scriptstr[8192+1],coinaddr[65],asmstr[16384]; int32_t i,asmtype; struct vin_info V; char scriptstr[8192+1],asmstr[16384]; int32_t i,m,n,scriptlen,asmtype; struct vin_info *vp;
uint8_t addrtype,space[8192]; uint8_t space[8192]; cJSON *addrs,*skey,*json = cJSON_CreateObject();
cJSON *addrs,*skey,*json = cJSON_CreateObject(); vp = calloc(1,sizeof(*vp));
jaddnum(json,"value",dstr(vout->value)); jaddnum(json,"value",dstr(vout->value));
jaddnum(json,"n",txi); jaddnum(json,"n",txi);
//"scriptPubKey":{"asm":"OP_DUP OP_HASH160 5f69cb73016264270dae9f65c51f60d0e4d6fd44 OP_EQUALVERIFY OP_CHECKSIG","reqSigs":1,"type":"pubkeyhash","addresses":["RHyh1V9syARTf2pyxibz7v27D5paBeWza5"]} //"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) ) if ( vout->pk_script != 0 && vout->pk_scriptlen*2+1 < sizeof(scriptstr) )
{ {
memset(&V,0,sizeof(V)); memset(vp,0,sizeof(*vp));
if ( (asmtype= iguana_calcrmd160(coin,&V,vout->pk_script,vout->pk_scriptlen,txid,txi,0xffffffff)) >= 0 ) if ( (asmtype= iguana_calcrmd160(coin,vp,vout->pk_script,vout->pk_scriptlen,txid,txi,0xffffffff)) >= 0 )
{ {
skey = cJSON_CreateObject(); 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 ) if ( asmstr[0] != 0 )
jaddstr(skey,"asm",asmstr); jaddstr(skey,"asm",asmstr);
addrs = cJSON_CreateArray(); addrs = cJSON_CreateArray();
if ( V.M == 0 ) if ( vp->N == 1 )
{ {
if ( asmtype == 2 ) if ( asmtype == 2 )
{ {
jaddnum(skey,"reqSigs",1); jaddnum(skey,"reqSigs",1);
jaddstr(skey,"type","pubkeyhash"); jaddstr(skey,"type","pubkeyhash");
} }
if ( coinaddr[0] != 0 ) if ( vp->coinaddr[0] != 0 )
jaddistr(addrs,coinaddr); jaddistr(addrs,vp->coinaddr);
} }
else else
{ {
jaddnum(skey,"reqSigs",V.M); jaddnum(skey,"reqSigs",vp->M);
for (i=0; i<V.N; i++) for (i=0; i<vp->N; i++)
{ {
btc_convrmd160(coinaddr,coin->chain->pubtype,V.signers[i].pubkey); //btc_convrmd160(coinaddr,coin->chain->pubtype,V.signers[i].pubkey);
jaddistr(addrs,coinaddr); jaddistr(addrs,vp->signers[i].coinaddr);
} }
} }
jadd(skey,"addresses",addrs); 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)); jaddstr(json,"txid",bits256_str(str,vin->prev_hash));
jaddnum(json,"vout",vout); jaddnum(json,"vout",vout);
sigjson = cJSON_CreateObject(); sigjson = cJSON_CreateObject();
jaddstr(sigjson,"redeemScript",scriptstr); jaddstr(sigjson,"hex",scriptstr);
jadd(json,"scriptSig",sigjson); jadd(json,"scriptSig",sigjson);
} }
return(json); return(json);
} }
cJSON *iguana_txjson(struct iguana_info *coin,struct iguana_txid *tx,int32_t height) int32_t iguana_vinparse(struct iguana_info *coin,int32_t rwflag,uint8_t *serialized,struct iguana_msgvin *msg)
{
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 len = 0; int32_t len = 0;
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->prev_hash),msg->prev_hash.bytes); 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++) 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 ) if ( array != 0 )
jaddi(array,iguana_vinjson(coin,&msg->vins[i])); 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); 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]; int32_t i,numvins,numvouts,len = 0; cJSON *array=0; bits256 txid; char vpnstr[64];
memset(msg,0,sizeof(*msg)); 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->lock_time = juint(txobj,"locktime");
msg->txid = jbits256(txobj,"txid"); msg->txid = jbits256(txobj,"txid");
*txstartp = len;
msg->allocsize = iguana_rwmsgtx(coin,1,0,&serialized[len],maxsize-len,msg,&txid,vpnstr); 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)); //char str[65]; printf("json -> %s\n",bits256_str(str,txid));
return(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; vpnstr[0] = 0;
//char str[65]; printf("%d of %d: %s\n",i,msg.txn_count,bits256_str(str,tx.txid)); //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); txbytes = malloc(n*2+1);
init_hexbytes_noT(txbytes,serialized,n); 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(); char asmstr[IGUANA_MAXSCRIPTSIZE*3]; int32_t j,n,siglen,plen; uint8_t sha256[32];
vpnstr[0] = 0; j = n = 0;
serialized = malloc(IGUANA_MAXPACKETSIZE); *hashtypep = SIGHASH_ALL;
if ( (n= iguana_rwmsgtx(coin,1,json,serialized,IGUANA_MAXPACKETSIZE,msgtx,&txid,vpnstr)) < 0 ) 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); vp->type = type;
return(json); j = 0;
} while ( ((plen= scriptsig[n]) == 33 || plen == 65 ) && j < 16 )
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; memcpy(vp->signers[j].pubkey,&scriptsig[n+1],plen);
if ( (tx= iguana_txidfind(coin,&height,&T,txid)) != 0 ) vcalc_sha256(0,sha256,vp->signers[j].pubkey,plen);
{ calc_rmd160(0,vp->signers[j].rmd160,sha256,sizeof(sha256));
*scriptlenp = iguana_voutset(coin,scriptspace,asmstr,height,&v,tx,vout); if ( j == 0 )
return(numpubs); memcpy(vp->rmd160,vp->signers[j].rmd160,20);
} n += (plen + 1);
j++;
} }
//char *str = "2103506a52e95cdfbb9d17d702af6259ba7de8b7a604007999e0266edbf6e4bb6974ac"; if ( n < len && (scriptsig[n] == 0x4c || scriptsig[n] == 0x4d) )
char *str = "76a914010966776006953d5567439e5e39f86a0d273bee88ac"; {
*scriptlenp = (int32_t)strlen(str) >> 1; if ( scriptsig[n] == 0x4c )
decode_hex(scriptspace,*scriptlenp,str); vp->p2shlen = scriptsig[n+1], n += 2;
//pubkeys[0] = clonestr("03506a52e95cdfbb9d17d702af6259ba7de8b7a604007999e0266edbf6e4bb6974"); else vp->p2shlen = ((uint32_t)scriptsig[n+1] + ((uint32_t)scriptsig[n+2] << 8)), n += 3;
pubkeys[0] = clonestr("0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6"); memcpy(vp->p2shscript,&scriptsig[n],vp->p2shlen);
return(numpubs); vp->type = IGUANA_SCRIPT_P2SH;
} }
/*if ( len == 0 )
int32_t bitcoin_hashtype(uint8_t *script,int32_t scriptlen,uint8_t *pk_script,int32_t pk_scriptlen) {
{ // txid.(eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2).v1
return(SIGHASH_ALL); 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]; bits256 txid,sigtxid,revsigtxid; char txidstr[128],bigstr[2560],coinaddr[64],vpnstr[64],str[65];
uint8_t *sig,mypubkey[128],pubkey[128],sigspace[8192],*saveinput,scriptspace[8192]; uint8_t *sig,*pubkey,*saveinput; struct vin_info *vp;
bits256 txid,sigtxid,revsigtxid,mypub; int32_t n2,i,j,k,plen,vini=0,flag,numvins,hashtype,retval,siglen,asmtype;
int32_t n2,i,j,numpubs,plen,scriptlen,vini=0,siglen,numvins,hashtype,myvin = 1;
vpnstr[0] = 0; vpnstr[0] = 0;
memset(pubkeys,0,sizeof(pubkeys)); *signedtx = 0;
memset(signedtxidp,0,sizeof(*signedtxidp));
numvins = msgtx->tx_in; numvins = msgtx->tx_in;
mypub = bitcoin_pubkey(mypubkey,myprivkey); retval = -numvins;
for (vini=0; vini<numvins; vini++) for (vini=0; vini<numvins; vini++)
{ {
saveinput = msgtx->vins[vini].script;
vp = &V[vini];
for (i=0; i<numvins; i++) for (i=0; i<numvins; i++)
msgtx->vins[i].scriptlen = 0; msgtx->vins[i].scriptlen = 0;
saveinput = msgtx->vins[vini].script;
sig = &msgtx->vins[vini].script[1]; sig = &msgtx->vins[vini].script[1];
siglen = msgtx->vins[vini].script[0]; siglen = msgtx->vins[vini].script[0] - 1;
numpubs = bitcoin_outputscript(coin,pubkeys,&scriptlen,scriptspace,msgtx->vins[vini].prev_hash,msgtx->vins[vini].prev_vout); vp->vin = msgtx->vins[vini];
msgtx->vins[vini].scriptlen = scriptlen; flag = 0;
msgtx->vins[vini].script = scriptspace; for (k=0; k<2; k++)
for (j=0; j<numpubs; j++)
{ {
plen = (int32_t)strlen(pubkeys[j]); asmtype = (k == 0) ? IGUANA_SCRIPT_76A988AC : IGUANA_SCRIPT_76AC;
plen >>= 1; if ( bitcoin_scriptget(coin,&hashtype,vp,saveinput,scriptlens[vini],asmtype) < 0 )
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 )
{ {
n2 += iguana_rwnum(1,&serialized[n2],sizeof(hashtype),&hashtype); printf("cant get script for (%s).v%d\n",bits256_str(str,vp->vin.prev_hash),vp->vin.prev_vout);
revsigtxid = bits256_doublesha256(txidstr,serialized,n2); continue;
for (i=0; i<sizeof(revsigtxid); i++) }
sigtxid.bytes[31-i] = revsigtxid.bytes[i]; msgtx->vins[vini].script = vp->spendscript;
if ( 1 && myvin != 0 ) 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; printf("illegal plen.%d [%02x]\n",plen,pubkey[0]);
siglen = bitcoin_sign(sig,sizeof(sigspace),sigtxid.bytes,sizeof(sigtxid),myprivkey); break;
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);
} }
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); n2 += iguana_rwnum(1,&serialized[n2],sizeof(hashtype),&hashtype);
printf("(%s) doesnt verify hash2.%s\n",bigstr,bits256_str(str,sigtxid)); revsigtxid = bits256_doublesha256(txidstr,serialized,n2);
return(-1); for (i=0; i<sizeof(revsigtxid); i++)
} else printf("SIG.%d VERIFIED\n",vini); sigtxid.bytes[31-i] = revsigtxid.bytes[i];
} else return(-1); 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)); //printf("privkey.%s\n",bits256_str(str,privkey));
@ -1052,17 +1102,16 @@ ffffffff\
76a914097072524438d003d23a2f23edb65aae1bb3e46988ac\ 76a914097072524438d003d23a2f23edb65aae1bb3e46988ac\
00000000"; 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; 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); len = (int32_t)strlen(rawtxstr);
maxsize = len + 32768; maxsize = len + 32768;
serialized = calloc(1,maxsize); serialized = calloc(1,maxsize);
serialized2 = calloc(1,maxsize); serialized2 = calloc(1,maxsize);
len >>= 1; len >>= 1;
vpnstr[0] = 0; vpnstr[0] = 0;
decode_hex(myprivkey.bytes,sizeof(myprivkey),"18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725");
decode_hex(serialized,len,rawtxstr); decode_hex(serialized,len,rawtxstr);
memset(&msgtx,0,sizeof(msgtx)); memset(&msgtx,0,sizeof(msgtx));
if ( iguana_rwmsgtx(coin,0,0,serialized,maxsize,&msgtx,&txid,vpnstr) > 0 ) 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)); scriptlens = calloc(numvins,sizeof(*scriptlens));
for (i=0; i<numvins; i++) for (i=0; i<numvins; i++)
scriptlens[i] = msgtx.vins[i].scriptlen; 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; retval = 0;
else printf("bitcoin_verifytx: bitcoin_verifyvins error\n");
for (i=0; i<numvins; i++)
msgtx.vins[i].scriptlen = scriptlens[i];
free(scriptlens); free(scriptlens);
} } else printf("bitcoin_verifytx: error iguana_rwmsgtx\n");
free(serialized), free(serialized2); free(serialized), free(serialized2);
return(retval); 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) 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; 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; rawtxstr = refstr;
maxsize = len + 32768; maxsize = len + 32768;
serialized = calloc(1,maxsize); serialized = calloc(1,maxsize);
serialized2 = calloc(1,maxsize); serialized2 = calloc(1,maxsize);
len >>= 1; len >>= 1;
V = 0;
vpnstr[0] = 0; vpnstr[0] = 0;
decode_hex(myprivkey.bytes,sizeof(myprivkey),"18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725");
memset(&msgtx,0,sizeof(msgtx)); memset(&msgtx,0,sizeof(msgtx));
if ( len < maxsize ) if ( len < maxsize )
{ {
decode_hex(serialized,len,rawtxstr); decode_hex(serialized,len,rawtxstr);
@ -1103,16 +1269,16 @@ decode_hex(myprivkey.bytes,sizeof(myprivkey),"18E14A7B6A307F426A94F8114701E7C8E7
free(serialized), free(serialized2); free(serialized), free(serialized2);
return(cJSON_Parse("{\"error\":\"cant parse txbytes\"}")); return(cJSON_Parse("{\"error\":\"cant parse txbytes\"}"));
} }
scriptlens = calloc(msgtx.tx_in,sizeof(*scriptlens)); V = calloc(msgtx.tx_in,sizeof(*V));
for (i=0; i<msgtx.tx_in; i++) {
scriptlens[i] = msgtx.vins[i].scriptlen; //char *pstr; int32_t plen;
if ( bitcoin_verifyvins(coin,scriptlens,&msgtx,serialized2,maxsize,myprivkey) < 0 ) decode_hex(V[0].signers[0].privkey.bytes,sizeof(V[0].signers[0].privkey),"18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725");
printf("sig verification error\n"); //pstr = "0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6";
else printf("sigs verified\n"); //plen = (int32_t)strlen(pstr);
for (i=0; i<msgtx.tx_in; i++) //decode_hex(V[0].signers[0].pubkey,plen,pstr);
msgtx.vins[i].scriptlen = scriptlens[i]; }
free(scriptlens); if ( bitcoin_verifytx(coin,&signedtxid,&signedtx,rawtxstr,V) != 0 )
printf("bitcoin_verifytx error\n");
jadd(retjson,"result",txjson); jadd(retjson,"result",txjson);
if ( (tp= iguana_txidfind(coin,&height,&T,txid)) != 0 ) 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 ) 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); printf("bitcoin_txtest: n.%d vs n2.%d\n",n,n2);
free(serialized), free(serialized2); free(serialized), free(serialized2), free(V);
return(retjson); return(retjson);
} }
if ( bits256_cmp(checktxid,txid) != 0 ) if ( bits256_cmp(checktxid,txid) != 0 )
{ {
printf("bitcoin_txtest: txid.%s vs check.%s\n",bits256_str(str,txid),bits256_str(str2,checktxid)); 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 ) if ( bits256_cmp(checktxid,txid) != 0 )
{ {
printf("bitcoin_txtest: txid.%s vs check2.%s\n",bits256_str(str,txid),bits256_str(str2,checktxid)); 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); return(retjson);
} }
free(serialized), free(serialized2); free(serialized), free(serialized2);
return(cJSON_Parse("{\"error\":\"testing bitcoin txbytes\"}")); 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 EXCHANGE_NAME "bitcoin"
#define UPDATE bitcoin ## _price #define UPDATE bitcoin ## _price
#define SUPPORTS bitcoin ## _supports #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) 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) char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson)

1
iguana/exchanges/bitcoin.h

@ -22,6 +22,7 @@
#define SIGHASH_SINGLE 3 #define SIGHASH_SINGLE 3
#define SIGHASH_ANYONECANPAY 0x80 #define SIGHASH_ANYONECANPAY 0x80
#define SCRIPT_OP_NOP 0x00
#define SCRIPT_OP_TRUE 0x51 #define SCRIPT_OP_TRUE 0x51
#define SCRIPT_OP_2 0x52 #define SCRIPT_OP_2 0x52
#define SCRIPT_OP_3 0x53 #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 DEFAULT_NXT_DEADLINE 720
#define issue_NXTPOST(cmdstr) bitcoind_RPC(0,"curl",myinfo->NXTAPIURL,0,0,cmdstr) #define issue_NXTPOST(cmdstr) bitcoind_RPC(0,"curl",myinfo->NXTAPIURL,0,0,cmdstr)
#define NXT_MSTYPE 5 #define NXT_MSTYPE 5
#define NXT_ASSETTYPE 2 #define NXT_ASSETTYPE 2
#define NXT_GENESISTIME 1385294400 #define NXT_GENESISTIME 1385294400
cJSON *_issue_NXTjson(struct supernet_info *myinfo,char *extra) cJSON *_issue_NXTjson(struct supernet_info *myinfo,char *extra)
{ {
char cmd[4096],*jsonstr; cJSON *json = 0; char cmd[4096],*jsonstr; cJSON *json = 0;
@ -101,6 +101,48 @@ uint32_t get_blockutime(struct supernet_info *myinfo,uint32_t blocknum)
return(timestamp); 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] = char *MGWassets[][3] =
{ {
{ "12659653638116877017", "BTC", "8" }, { "12659653638116877017", "BTC", "8" },
@ -404,6 +446,101 @@ int32_t NXT_assetpolarity(struct supernet_info *myinfo,char *name)
else return(0); 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 EXCHANGE_NAME "nxtae"
#define UPDATE nxtae ## _price #define UPDATE nxtae ## _price
#define SUPPORTS nxtae ## _supports #define SUPPORTS nxtae ## _supports
@ -544,7 +681,7 @@ double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchang
return(hbla); 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; int32_t deadline = 1 + 20; uint64_t txid = 0; struct destbuf errstr; char cmd[4096],secret[8192],*jsonstr; cJSON *json;
if ( retjsonstrp != 0 ) if ( retjsonstrp != 0 )
@ -564,21 +701,18 @@ uint64_t submit_triggered_nxtae(struct supernet_info *myinfo,int32_t dotrade,cha
} }
if ( otherNXT != 0 ) if ( otherNXT != 0 )
sprintf(cmd+strlen(cmd),"&recipient=%llu",(long long)otherNXT); 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 ( triggerhash != 0 && triggerhash[0] != 0 )
{ sprintf(cmd+strlen(cmd),"&phased=true&phasingFinishHeight=%u&phasingVotingModel=4&phasingQuorum=1&phasingLinkedFullHash=%s",triggerheight,triggerhash);
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);
}
if ( comment != 0 && comment[0] != 0 ) if ( comment != 0 && comment[0] != 0 )
sprintf(cmd+strlen(cmd),"&message=%s",comment); sprintf(cmd+strlen(cmd),"&message=%s",comment);
if ( dotrade == 0 ) if ( dotrade == 0 )
{ {
if ( retjsonstrp != 0 ) if ( retjsonstrp != 0 )
{ {
json = cJSON_CreateObject(); strcat(cmd,"&broadcast=false");
jaddstr(json,"submit",cmd); *retjsonstrp = issue_NXTPOST(cmd);
*retjsonstrp = jprint(json,1);
} }
return(0); return(0);
} }
@ -603,6 +737,30 @@ uint64_t submit_triggered_nxtae(struct supernet_info *myinfo,int32_t dotrade,cha
return(txid); 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) 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; 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 ) if ( is_MS == 0 )
cmdstr = dir > 0 ? "placeBidOrder" : "placeAskOrder"; cmdstr = dir > 0 ? "placeBidOrder" : "placeAskOrder";
else cmdstr = dir > 0 ? "currencyBuy" : "currencySell"; 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 ) if ( errstr != 0 )
sprintf(retbuf,"{\"error\":\"%s\"}",errstr), free(errstr); sprintf(retbuf,"{\"error\":\"%s\"}",errstr), free(errstr);
else sprintf(retbuf,"{\"result\":\"success\",\"txid\":\"%llu\"}",(long long)txid); 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 vin_info
{ {
struct iguana_msgvin vin; struct iguana_msgvin vin;
int32_t M,N,validmask,spendlen,type; int32_t M,N,validmask,spendlen,type,p2shlen;
struct vin_signer signers[16]; struct vin_signer signers[16];
char coinaddr[65]; char coinaddr[65];
uint8_t rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE]; uint8_t rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE],p2shscript[IGUANA_MAXSCRIPTSIZE];
}; };
// peers // peers
@ -588,7 +588,7 @@ double dxblend(double *destp,double val,double decay);
// json // json
int32_t iguana_processjsonQ(struct iguana_info *coin); // reentrant, can be called during any idletime 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 *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); 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); 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_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); 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); 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(); struct iguana_info *iguana_coinselect();
void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr); 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); 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); 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); 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_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); 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); 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); 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_HOPS 3
#define INSTANTDEX_DURATION 60 #define INSTANTDEX_DURATION 60
#define INSTANTDEX_PROPOSE 1 #define INSTANTDEX_NXTOFFER 1
#define INSTANTDEX_ACCEPT 2 #define INSTANTDEX_REQUEST 2
#define INSTANTDEX_CONFIRM 3 #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(); cJSON *argjson = cJSON_CreateObject();
if ( reference != 0 ) if ( reference != 0 )
jaddstr(argjson,"refstr",reference); jaddstr(argjson,"refstr",reference);
if ( message != 0 && message[0] != 0 ) if ( message != 0 && message[0] != 0 )
jaddstr(argjson,"message",message); jaddstr(argjson,"message",message);
jaddbits256(argjson,"basetxid",basetxid); if ( othercoinaddr != 0 && othercoinaddr[0] != 0 )
jaddbits256(argjson,"reltxid",reltxid); 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 ( iter != 3 )
{ {
if ( val == 0 ) if ( val == 0 )
@ -204,11 +213,56 @@ double instantdex_aveprice(struct supernet_info *myinfo,struct exchange_quote *s
return(0); 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; struct NXT_tx feeT; char fullhash[256],*othercoinaddr; cJSON *feejson; uint64_t assetbits = 0;
double volume,price,aveprice,totalvol; cJSON *newjson; int32_t duration,flags,nextcmd; char *base,*rel,*request,*refstr,*nextcmdstr,*message,*traderip,*otherNXTaddr;
int32_t num,depth; struct exchange_quote sortbuf[1000]; bits256 basetxid,reltxid; 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 ) if ( argjson != 0 )
{ {
num = 0; num = 0;
@ -227,40 +281,73 @@ char *instantdex_request(struct supernet_info *myinfo,char *cmdstr,struct instan
printf("got my own request\n"); printf("got my own request\n");
return(clonestr("{\"result\":\"got my own request\"}")); 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); if ( (price= instantdex_acceptable(myinfo,0,refstr,base,rel,volume)) > 0. )
OS_randombytes(basetxid.bytes,sizeof(basetxid)); {
OS_randombytes(reltxid.bytes,sizeof(reltxid)); // sends NXT assetid, volume and desired
char str[65]; printf("GENERATE txid.%s aveprice %.8f vol %f\n",bits256_str(str,basetxid),aveprice,totalvol); if ( strcmp(base,"NXT") == 0 || strcmp(base,"nxt") == 0 )
nextcmd = INSTANTDEX_PROPOSE; assetbits = NXT_ASSETID;
nextcmdstr = "proposal"; else if ( is_decimalstr(base) > 0 )
message = "hello"; assetbits = calc_nxt64bits(base);
price = aveprice; if ( assetbits != 0 )
volume = totalvol; {
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 else
{ {
basetxid = jbits256(argjson,"basetxid");
reltxid = jbits256(argjson,"reltxid");
if ( strcmp(cmdstr,"proposal") == 0 ) if ( strcmp(cmdstr,"proposal") == 0 )
{ {
// proposal:
// NXT node submits phasedtx that refers to it, but it wont confirm
nextcmd = INSTANTDEX_ACCEPT; nextcmd = INSTANTDEX_ACCEPT;
nextcmdstr = "accept"; nextcmdstr = "accept";
message = "world"; message = "";
//instantdex_phasetxsubmit(refstr);
} }
else if ( strcmp(cmdstr,"accept") == 0 ) 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; nextcmd = INSTANTDEX_CONFIRM;
nextcmdstr = "confirm"; nextcmdstr = "confirm";
message = "confirmed"; message = "";
//instantdex_phasedtxverify();
//instantdex_cltvbroadcast();
//instantdex_releasetrigger();
} }
else if ( strcmp(cmdstr,"confirm") == 0 ) 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\"}")); 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,"price",price);
jaddnum(newjson,"volume",volume); 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[] = 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 }, { "NXToffer", instantdex_request }, { "request", instantdex_request },
{ "accept", instantdex_request }, { "confirm", instantdex_request }, { "proposal", instantdex_request },
{ "accept", instantdex_request },
{ "confirm", instantdex_request },
}; };
char *retstr = 0; int32_t i; uint64_t cmdbits; char *retstr = 0; int32_t i; uint64_t cmdbits;
if ( cmds[0].cmdbits == 0 ) 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" #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; int32_t hops = INSTANTDEX_HOPS; cJSON *argjson;
if ( remoteaddr == 0 ) if ( remoteaddr == 0 )
@ -355,21 +471,35 @@ THREE_STRINGS_AND_DOUBLE(InstantDEX,request,reference,base,rel,volume)
jaddstr(argjson,"base",base); jaddstr(argjson,"base",base);
jaddstr(argjson,"rel",rel); jaddstr(argjson,"rel",rel);
jaddnum(argjson,"volume",volume); 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!\"}")); } 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; int32_t hops = INSTANTDEX_HOPS; cJSON *argjson;
if ( remoteaddr == 0 ) 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)); return(instantdex_sendcmd(myinfo,argjson,"proposal",myinfo->ipaddr,hops));
} else return(clonestr("{\"error\":\"InstantDEX API proposal only local usage!\"}")); } 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; int32_t hops = INSTANTDEX_HOPS; cJSON *argjson;
if ( remoteaddr == 0 ) 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); argjson = InstantDEX_argjson(reference,message,basetxid,reltxid,INSTANTDEX_CONFIRM,baseheight,relheight);
return(instantdex_sendcmd(myinfo,argjson,"confirm",myinfo->ipaddr,hops)); return(instantdex_sendcmd(myinfo,argjson,"confirm",myinfo->ipaddr,hops));
} else return(clonestr("{\"error\":\"InstantDEX API confirm only local usage!\"}")); } else return(clonestr("{\"error\":\"InstantDEX API confirm only local usage!\"}"));
} }*/
#include "../includes/iguana_apiundefs.h" #include "../includes/iguana_apiundefs.h"

8
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_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_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_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_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"))) #define IGUANA_HELP_SI(agent,name,str,val) array = helpjson(IGUANA_ARGS,#agent,#name,helparray2(cJSON_CreateArray(),helpitem(#str,"string"),helpitem(#val,"int")))
@ -164,7 +165,8 @@ cJSON *SuperNET_helpjson()
#define THREE_STRINGS_AND_THREE_DOUBLES IGUANA_HELP_SSSDDD #define THREE_STRINGS_AND_THREE_DOUBLES IGUANA_HELP_SSSDDD
#define THREE_STRINGS_AND_DOUBLE IGUANA_HELP_SSSD #define THREE_STRINGS_AND_DOUBLE IGUANA_HELP_SSSD
#define STRING_AND_DOUBLE IGUANA_HELP_SD #define STRING_AND_DOUBLE IGUANA_HELP_SD
#define TWO_STRINGS_AND_TWO_DOUBLES IGUANA_HELP_SSDD
#include "../includes/iguana_apideclares.h" #include "../includes/iguana_apideclares.h"
#include "../includes/iguana_apiundefs.h" #include "../includes/iguana_apiundefs.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_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_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_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_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))) #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,7 +923,8 @@ 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_THREE_DOUBLES IGUANA_DISPATCH_SSSDDD
#define THREE_STRINGS_AND_DOUBLE IGUANA_DISPATCH_SSSD #define THREE_STRINGS_AND_DOUBLE IGUANA_DISPATCH_SSSD
#define STRING_AND_DOUBLE IGUANA_DISPATCH_SD #define STRING_AND_DOUBLE IGUANA_DISPATCH_SD
#define TWO_STRINGS_AND_TWO_DOUBLES IGUANA_DISPATCH_SSDD
#include "../includes/iguana_apideclares.h" #include "../includes/iguana_apideclares.h"
//#undef IGUANA_ARGS //#undef IGUANA_ARGS

5
iguana/iguana_pubkeys.c

@ -345,7 +345,10 @@ cstring *base58_decode_check(uint8_t *addrtype,const char *s_in)
} }
else 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); 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->value = u->value;
vout->pk_script = scriptspace; vout->pk_script = scriptspace;
memset(&V,0,sizeof(V)); 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; vout->pk_scriptlen = scriptlen;
return(scriptlen); return(scriptlen);

2
iguana/main.c

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

6
includes/iguana_apideclares.h

@ -44,10 +44,12 @@ STRING_AND_INT(InstantDEX,pollgap,exchange,pollgap);
ZERO_ARGS(InstantDEX,allexchanges); ZERO_ARGS(InstantDEX,allexchanges);
STRING_ARG(InstantDEX,allpairs,exchange); 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); 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,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,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,confirm,reference,message,basetxid,reltxid,baseheight,relheight);
THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission);
STRING_AND_DOUBLE(tradebot,monitorall,exchange,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_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_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_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_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_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) #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_INTS IGUANA_CFUNC_SSSIII
#define THREE_STRINGS_AND_THREE_DOUBLES IGUANA_CFUNC_SSSDDD #define THREE_STRINGS_AND_THREE_DOUBLES IGUANA_CFUNC_SSSDDD
#define THREE_STRINGS_AND_DOUBLE IGUANA_CFUNC_SSSD #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 THREE_STRINGS_AND_DOUBLE
#undef STRING_AND_DOUBLE #undef STRING_AND_DOUBLE
#undef FOUR_STRINGS #undef FOUR_STRINGS
#undef TWO_STRINGS_AND_TWO_DOUBLES
#undef IGUANA_ARGS #undef IGUANA_ARGS
#undef IGUANA_CALLARGS #undef IGUANA_CALLARGS

Loading…
Cancel
Save