From 064f1943486d76c9130a9d1ff0cabf854ad4f821 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 6 Aug 2016 11:01:02 -0300 Subject: [PATCH] test --- iguana/exchanges/bitcoin.h | 2 +- iguana/iguana_payments.c | 2 +- iguana/iguana_scripts.c | 50 ++++++++++------- iguana/iguana_sign.c | 107 +++++++++++++++---------------------- includes/iguana_structs.h | 4 +- 5 files changed, 77 insertions(+), 88 deletions(-) diff --git a/iguana/exchanges/bitcoin.h b/iguana/exchanges/bitcoin.h index 49f623beb..2bb2c5d9c 100755 --- a/iguana/exchanges/bitcoin.h +++ b/iguana/exchanges/bitcoin.h @@ -53,7 +53,7 @@ int32_t bitcoin_revealsecret160(uint8_t *script,int32_t n,uint8_t secret160[20]) int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20]); int32_t bitcoin_pubkeylen(const uint8_t *pubkey); -int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *suffixp,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t spendtype); +int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,uint32_t *sigsizep,uint32_t *pubkeysizep,uint8_t **userdatap,uint32_t *userdatalenp,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t spendtype); int32_t iguana_expandscript(struct iguana_info *coin,char *asmstr,int32_t maxlen,uint8_t *script,int32_t scriptlen); int32_t bitcoin_scriptsig(struct iguana_info *coin,uint8_t *script,int32_t n,const struct vin_info *vp,struct iguana_msgtx *msgtx); char *iguana_scriptget(struct iguana_info *coin,char *scriptstr,char *asmstr,int32_t max,int32_t hdrsi,uint32_t unspentind,bits256 txid,int32_t vout,uint8_t *rmd160,int32_t type,uint8_t *pubkey33); diff --git a/iguana/iguana_payments.c b/iguana/iguana_payments.c index 218266262..d86464ca3 100755 --- a/iguana/iguana_payments.c +++ b/iguana/iguana_payments.c @@ -932,7 +932,7 @@ char *iguana_validaterawtx(struct supernet_info *myinfo,struct iguana_info *coin msgtx->vins[i].spendscript = V[i].spendscript; msgtx->vins[i].spendlen = V[i].spendlen; V[i].hashtype = iguana_vinscriptparse(coin,&V[i],&sigsize,&pubkeysize,&p2shsize,&suffixlen,msgtx->vins[i].vinscript,msgtx->vins[i].scriptlen); - V[i].suffixlen = suffixlen; + V[i].userdatalen = suffixlen; memcpy(V[i].spendscript,msgtx->vins[i].spendscript,msgtx->vins[i].spendlen); V[i].spendlen = msgtx->vins[i].spendlen; if ( msgtx->vins[i].sequence < IGUANA_SEQUENCEID_FINAL ) diff --git a/iguana/iguana_scripts.c b/iguana/iguana_scripts.c index be62e5329..2602d6b63 100755 --- a/iguana/iguana_scripts.c +++ b/iguana/iguana_scripts.c @@ -448,11 +448,12 @@ int32_t iguana_calcrmd160(struct iguana_info *coin,char *asmstr,struct vin_info //error memalloc mem.0x7f6fc6e4a2a8 94.242.229.158 alloc 1 used 2162688 totalsize.2162688 -> 94.242.229.158 (nil) -int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *suffixp,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t spendtype) +int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,uint32_t *sigsizep,uint32_t *pubkeysizep,uint8_t **userdatap,uint32_t *userdatalenp,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t spendtype) { - char asmstr[IGUANA_MAXSCRIPTSIZE*3]; int32_t j,n,siglen,plen; + char asmstr[IGUANA_MAXSCRIPTSIZE*3]; int32_t j,n,siglen,plen; uint8_t *p2shscript; j = n = 0; - *suffixp = *pubkeysizep = 0; + *userdatap = 0; + *userdatalenp = *pubkeysizep = 0; *hashtypep = SIGHASH_ALL; while ( (siglen= scriptsig[n]) >= 70 && siglen <= 73 && n+siglen < len && j < 16 ) { @@ -476,7 +477,7 @@ int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,uint32_t * vp->type = spendtype; if ( j == 0 ) { - *suffixp = len; + *userdatalenp = len; vp->spendlen = len; return(vp->spendlen); } @@ -492,21 +493,28 @@ int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,uint32_t * j++; } vp->numpubkeys = j; - if ( n+2 < len && (scriptsig[n] == 0x4c || scriptsig[n] == 0x4d) ) + *userdatap = &scriptsig[n]; + *userdatalenp = (len - n); + p2shscript = 0; + while ( n < len ) { - if ( scriptsig[n] == 0x4c ) - vp->p2shlen = scriptsig[n+1], n += 2; - else vp->p2shlen = ((uint32_t)scriptsig[n+1] + ((uint32_t)scriptsig[n+2] << 8)), n += 3; - //printf("p2sh opcode.%02x %02x %02x scriptlen.%d\n",scriptsig[n],scriptsig[n+1],scriptsig[n+2],vp->p2shlen); - if ( vp->p2shlen < IGUANA_MAXSCRIPTSIZE && n+vp->p2shlen <= len ) + if ( n+2 < len && (scriptsig[n] == 0x4c || scriptsig[n] == 0x4d) ) { - memcpy(vp->p2shscript,&scriptsig[n],vp->p2shlen); - n += vp->p2shlen; - vp->type = IGUANA_SCRIPT_P2SH; - } else vp->p2shlen = 0; + if ( scriptsig[n] == 0x4c ) + vp->p2shlen = scriptsig[n+1], n += 2; + else vp->p2shlen = ((uint32_t)scriptsig[n+1] + ((uint32_t)scriptsig[n+2] << 8)), n += 3; + //printf("p2sh opcode.%02x %02x %02x scriptlen.%d\n",scriptsig[n],scriptsig[n+1],scriptsig[n+2],vp->p2shlen); + if ( vp->p2shlen < IGUANA_MAXSCRIPTSIZE && n+vp->p2shlen <= len ) + { + p2shscript = &scriptsig[n]; + memcpy(vp->p2shscript,&scriptsig[n],vp->p2shlen); + n += vp->p2shlen; + vp->type = IGUANA_SCRIPT_P2SH; + } else vp->p2shlen = 0; + } } - if ( n < len ) - *suffixp = (len - n); + if ( *userdatap == p2shscript ) + *userdatap = 0; /*if ( len == 0 ) { // txid.(eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2).v1 @@ -518,15 +526,17 @@ int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,uint32_t * return(vp->spendlen); } -int32_t iguana_vinscriptparse(struct iguana_info *coin,struct vin_info *vp,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *p2shsizep,uint32_t *suffixp,uint8_t *vinscript,int32_t scriptlen) +int32_t iguana_vinscriptparse(struct iguana_info *coin,struct vin_info *vp,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *p2shsizep,uint32_t *userdatalenp,uint8_t *vinscript,int32_t scriptlen) { - int32_t hashtype; - *sigsizep = *pubkeysizep = *p2shsizep = *suffixp = 0; - if ( bitcoin_scriptget(coin,&hashtype,sigsizep,pubkeysizep,suffixp,vp,vinscript,scriptlen,0) < 0 ) + int32_t hashtype; uint8_t *userdata = 0; + *sigsizep = *pubkeysizep = *p2shsizep = *userdatalenp = 0; + if ( bitcoin_scriptget(coin,&hashtype,sigsizep,pubkeysizep,&userdata,userdatalenp,vp,vinscript,scriptlen,0) < 0 ) { printf("iguana_vinscriptparse: error parsing vinscript?\n"); return(-1); } + if ( userdata != 0 && *userdatalenp > 0 ) + memcpy(vp->userdata,userdata,*userdatalenp); if ( vp->type == IGUANA_SCRIPT_P2SH ) { *p2shsizep = vp->p2shlen + 1 + (vp->p2shlen >= 0xfd)*2; diff --git a/iguana/iguana_sign.c b/iguana/iguana_sign.c index 7c3792cb6..67d065ec9 100755 --- a/iguana/iguana_sign.c +++ b/iguana/iguana_sign.c @@ -20,12 +20,11 @@ int32_t iguana_vinparse(struct iguana_info *coin,int32_t rwflag,uint8_t *serialized,struct iguana_msgvin *msg) { - //int32_t sighash,i,plen,len = 0; struct vin_info V; uint32_t sigsize,pubkeysize,p2shsize,suffixlen; int32_t p2shlen,len = 0; uint32_t tmp; len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->prev_hash),msg->prev_hash.bytes); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->prev_vout),&msg->prev_vout); if ( rwflag == 1 ) - tmp = msg->scriptlen; + tmp = msg->scriptlen + msg->userdatalen + msg->p2shlen; len += iguana_rwvarint32(rwflag,&serialized[len],&tmp); if ( rwflag == 0 ) msg->scriptlen = tmp; @@ -42,31 +41,28 @@ int32_t iguana_vinparse(struct iguana_info *coin,int32_t rwflag,uint8_t *seriali else if ( msg->vinscript != 0 && msg->scriptlen > 0 ) { memcpy(&serialized[len],msg->vinscript,msg->scriptlen), len += msg->scriptlen; // pubkeys here - if ( msg->suffixlen > 0 && msg->redeemscript != 0 ) + if ( msg->userdatalen > 0 && msg->userdata != 0 ) { - printf("msgsuffixlen.%d\n",msg->suffixlen); - memcpy(&serialized[len],&msg->redeemscript[msg->scriptlen - msg->suffixlen],msg->suffixlen), len += msg->suffixlen; + printf("userdata.%d\n",msg->userdatalen); + memcpy(&serialized[len],msg->userdata,msg->userdatalen); + len += msg->userdatalen; } if ( (p2shlen= msg->p2shlen) > 0 && msg->redeemscript != 0 ) { - if ( p2shlen > msg->suffixlen ) + if ( p2shlen < 76 ) + serialized[len++] = p2shlen; + else if ( p2shlen <= 0xff ) { - p2shlen -= msg->suffixlen; - if ( p2shlen < 76 ) - serialized[len++] = p2shlen; - else if ( p2shlen <= 0xff ) - { - serialized[len++] = 0x4c; - serialized[len++] = p2shlen; - } - else if ( p2shlen <= 0xffff ) - { - serialized[len++] = 0x4d; - serialized[len++] = (p2shlen & 0xff); - serialized[len++] = ((p2shlen >> 8) & 0xff); - } else return(-1); - memcpy(&serialized[len],msg->redeemscript,p2shlen), len += p2shlen; + serialized[len++] = 0x4c; + serialized[len++] = p2shlen; } + else if ( p2shlen <= 0xffff ) + { + serialized[len++] = 0x4d; + serialized[len++] = (p2shlen & 0xff); + serialized[len++] = ((p2shlen >> 8) & 0xff); + } else return(-1); + memcpy(&serialized[len],msg->redeemscript,p2shlen), len += p2shlen; } } len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->sequence),&msg->sequence); @@ -117,24 +113,21 @@ cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin,bits256 jaddnum(json,"vout",vout); if ( bits256_nonz(sigtxid) != 0 ) jaddbits256(json,"sigtxid",sigtxid); - if ( vin->scriptlen > 0 ) + if ( vin->scriptlen > 0 ) // sigs iguana_addscript(coin,json,vin->vinscript,vin->scriptlen,"scriptSig"); - if ( vin->spendlen > 0 ) - iguana_addscript(coin,json,vin->spendscript,vin->spendlen,"scriptPubKey"); + if ( vin->userdatalen > 0 && vin->userdata != 0 ) + iguana_addscript(coin,json,vin->userdata,vin->userdatalen,"userdata"); if ( vin->p2shlen > 0 ) iguana_addscript(coin,json,vin->redeemscript,vin->p2shlen,"redeemScript"); - if ( vin->suffixlen > 0 ) - { - iguana_addscript(coin,json,&vin->redeemscript[vin->p2shlen],vin->suffixlen,"suffix"); - vin->p2shlen += vin->suffixlen; - } + if ( vin->spendlen > 0 ) + iguana_addscript(coin,json,vin->spendscript,vin->spendlen,"scriptPubKey"); } return(json); } int32_t iguana_parsevinobj(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_msgvin *vin,cJSON *vinobj,struct vin_info *V) { - struct iguana_waddress *waddr; struct iguana_waccount *wacct; int32_t i,n,plen,len = 0; char *suffixstr,*pubkeystr,*hexstr = 0,*redeemstr = 0,*spendstr = 0; cJSON *scriptjson = 0,*obj,*pubkeysjson = 0; + struct iguana_waddress *waddr; struct iguana_waccount *wacct; int32_t i,n,plen,len = 0; char *userdata,*pubkeystr,*hexstr = 0,*redeemstr = 0,*spendstr = 0; cJSON *scriptjson = 0,*obj,*pubkeysjson = 0; //printf("PARSEVIN.(%s) vin.%p\n",jprint(vinobj,0),vin); if ( V == 0 ) memset(vin,0,sizeof(*vin)); @@ -158,6 +151,11 @@ int32_t iguana_parsevinobj(struct supernet_info *myinfo,struct iguana_info *coin if ( (obj= jobj(vinobj,"redeemScript")) != 0 ) redeemstr = jstr(obj,"hex"); } + if ( (userdata= jstr(vinobj,"userdata")) == 0 || is_hexstr(userdata,(int32_t)strlen(userdata)) <= 0 ) + { + if ( (obj= jobj(vinobj,"userdata")) != 0 ) + userdata = jstr(obj,"hex"); + } } if ( hexstr != 0 ) { @@ -202,6 +200,15 @@ int32_t iguana_parsevinobj(struct supernet_info *myinfo,struct iguana_info *coin if ( vin->vinscript != 0 ) serialized = &vin->vinscript[vin->scriptlen]; len += vin->scriptlen; + if ( userdata != 0 ) + { + n = (int32_t)strlen(userdata) >> 1; + decode_hex(serialized,n,userdata); + vin->userdata = serialized; + V->userdatalen = vin->userdatalen = n; + memcpy(V->userdata,serialized,n); + serialized += n; + } if ( redeemstr != 0 ) { n = (int32_t)strlen(redeemstr) >> 1; @@ -209,20 +216,8 @@ int32_t iguana_parsevinobj(struct supernet_info *myinfo,struct iguana_info *coin vin->redeemscript = serialized; V->p2shlen = vin->p2shlen = n; memcpy(V->p2shscript,serialized,n); + serialized += n; } - if ( (suffixstr= jstr(vinobj,"suffix")) != 0 && is_hexstr(suffixstr,(int32_t)strlen(suffixstr)) > 0 ) - { - if ( vin->redeemscript == 0 ) - { - vin->redeemscript = serialized; - vin->redeemscript[0] = 0; - } - n = (int32_t)strlen(suffixstr) >> 1; - decode_hex(&vin->redeemscript[vin->p2shlen],n,suffixstr); - vin->p2shlen += n; - } - len += vin->p2shlen; - serialized = vin->redeemscript != 0 ? &vin->redeemscript[vin->p2shlen] : &serialized[len]; if ( spendstr != 0 ) { n = (int32_t)strlen(spendstr) >> 1; @@ -361,10 +356,7 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t rwflag,cJSON *json,uint8 if ( json != 0 ) jaddnum(json,"timestamp",msg->timestamp); } - //for (i=len; itx_in); - //printf(" tx_in.%08x\n",msg->tx_in); if ( rwflag == 0 ) { if ( msg->vins == 0 ) @@ -409,10 +401,7 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t rwflag,cJSON *json,uint8 jaddnum(json,"numvins",msg->tx_in); array = cJSON_CreateArray(); } - //for (i=len; itx_out); - //printf(" txout.%d\n",msg->tx_out); if ( rwflag == 0 ) { if ( msg->vouts == 0 ) @@ -635,13 +624,9 @@ int32_t iguana_msgtx_Vset(struct iguana_info *coin,uint8_t *serialized,int32_t m } } } - msgtx->vins[vini].scriptlen = scriptlen; printf("USERDATALEN.%d\n",vp->userdatalen); if ( vp->userdatalen != 0 ) - { - memcpy(&script[scriptlen],vp->userdata,vp->userdatalen); - scriptlen += vp->userdatalen; - } + memcpy(&script[scriptlen],vp->userdata,vp->userdatalen), scriptlen += vp->userdatalen; if ( (p2shlen= vp->p2shlen) > 0 ) { msgtx->vins[vini].redeemscript = &script[scriptlen]; @@ -659,14 +644,8 @@ int32_t iguana_msgtx_Vset(struct iguana_info *coin,uint8_t *serialized,int32_t m script[scriptlen++] = ((p2shlen >> 8) & 0xff); } else return(-1); memcpy(&script[scriptlen],vp->p2shscript,p2shlen), scriptlen += p2shlen; - if ( (msgtx->vins[vini].suffixlen= vp->suffixlen) > 0 ) - { - printf("suffixlen.%d\n",vp->suffixlen); - memcpy(&script[scriptlen],&vp->p2shscript[vp->p2shlen - vp->suffixlen],vp->suffixlen); - scriptlen += vp->suffixlen; - } - msgtx->vins[vini].scriptlen = scriptlen; } + msgtx->vins[vini].scriptlen = scriptlen; len += scriptlen; } return(len); @@ -742,7 +721,7 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char ** int32_t iguana_vininfo_create(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msgtx,cJSON *vins,int32_t numinputs,struct vin_info *V) { - int32_t i,plen,finalized = 1,len = 0; struct vin_info *vp; struct iguana_waccount *wacct; struct iguana_waddress *waddr; uint32_t sigsize,pubkeysize,p2shsize,suffixlen; + int32_t i,plen,finalized = 1,len = 0; struct vin_info *vp; struct iguana_waccount *wacct; struct iguana_waddress *waddr; uint32_t sigsize,pubkeysize,p2shsize,userdatalen; msgtx->tx_in = numinputs; maxsize -= (sizeof(struct iguana_msgvin) * msgtx->tx_in); msgtx->vins = (struct iguana_msgvin *)&serialized[maxsize]; @@ -761,8 +740,8 @@ int32_t iguana_vininfo_create(struct supernet_info *myinfo,struct iguana_info *c { msgtx->vins[i].spendscript = vp->spendscript; msgtx->vins[i].spendlen = vp->spendlen; - vp->hashtype = iguana_vinscriptparse(coin,V,&sigsize,&pubkeysize,&p2shsize,&suffixlen,vp->spendscript,vp->spendlen); - vp->suffixlen = suffixlen; + vp->hashtype = iguana_vinscriptparse(coin,vp,&sigsize,&pubkeysize,&p2shsize,&userdatalen,vp->spendscript,vp->spendlen); + vp->userdatalen = userdatalen; printf("V %.8f (%s) spendscript.[%d]\n",dstr(vp->amount),vp->coinaddr,vp->spendlen); } } diff --git a/includes/iguana_structs.h b/includes/iguana_structs.h index 9d007bc94..bdcfdf6f9 100755 --- a/includes/iguana_structs.h +++ b/includes/iguana_structs.h @@ -125,7 +125,7 @@ struct iguana_msgblock uint32_t txn_count; } __attribute__((packed)); -struct iguana_msgvin { bits256 prev_hash; uint8_t *vinscript,*spendscript,*redeemscript; uint32_t prev_vout,sequence; uint16_t scriptlen,p2shlen,suffixlen,spendlen; } __attribute__((packed)); +struct iguana_msgvin { bits256 prev_hash; uint8_t *vinscript,*userdata,*spendscript,*redeemscript; uint32_t prev_vout,sequence; uint16_t scriptlen,p2shlen,userdatalen,spendlen; } __attribute__((packed)); struct iguana_msgvout { uint64_t value; uint32_t pk_scriptlen; uint8_t *pk_script; } __attribute__((packed)); @@ -427,7 +427,7 @@ struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],r struct vin_info { struct iguana_msgvin vin; uint64_t amount; cJSON *extras; bits256 sigtxid; - int32_t M,N,validmask,spendlen,type,p2shlen,suffixlen,numpubkeys,numsigs,height,hashtype,userdatalen,suppress_pubkeys; + int32_t M,N,validmask,spendlen,type,p2shlen,numpubkeys,numsigs,height,hashtype,userdatalen,suppress_pubkeys; uint32_t sequence,unspentind; struct vin_signer signers[16]; char coinaddr[65]; uint8_t rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE],p2shscript[IGUANA_MAXSCRIPTSIZE],userdata[IGUANA_MAXSCRIPTSIZE]; };