From a2056c8954c82bfdd0a4f53df8a99d7613bbaf66 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 4 Feb 2016 22:06:23 -0300 Subject: [PATCH] reorder .md generation --- deprecated/obsolete.h | 137 +++++++++++++++++ iguana/exchanges/bitcoin.c | 286 +++++++++++++++++++++++++++------- iguana/iguana777.h | 14 +- iguana/iguana_json.c | 17 +-- iguana/iguana_pubkeys.c | 305 ------------------------------------- iguana/iguana_ramchain.c | 2 +- iguana/iguana_rpc.c | 14 +- 7 files changed, 397 insertions(+), 378 deletions(-) diff --git a/deprecated/obsolete.h b/deprecated/obsolete.h index 91acc327e..5b3239105 100644 --- a/deprecated/obsolete.h +++ b/deprecated/obsolete.h @@ -12954,5 +12954,142 @@ len = 0; 19\ 76a914097072524438d003d23a2f23edb65aae1bb3e46988ac\ 00000000"; + + char *iguana_txcreate(struct iguana_info *coin,uint8_t *space,int32_t maxlen,char *jsonstr) + { + struct iguana_txid T; struct iguana_msgvin *vins,*vin; struct iguana_msgvout *vouts,*vout; + char *redeemstr; + cJSON *array,*json,*item,*retjson = 0; bits256 scriptPubKey; int32_t i,numvins,numvouts,len = 0; + if ( (json= cJSON_Parse(jsonstr)) != 0 ) + { + memset(&T,0,sizeof(T)); + if ( (T.version= juint(json,"version")) == 0 ) + T.version = 1; + if ( (T.locktime= juint(json,"locktime")) == 0 ) + T.locktime = 0xffffffff; + vins = (struct iguana_msgvin *)&space[len]; + if ( (array= jarray(&numvins,json,"vins")) != 0 ) + { + len += sizeof(*vins) * numvins; + memset(vins,0,sizeof(*vins) * numvins); + //struct iguana_msgvin { bits256 prev_hash; uint8_t *script; uint32_t prev_vout,scriptlen,sequence; }; + for (i=0; iprev_hash = jbits256(item,"txid"); + vin->prev_vout = juint(item,"vout"); + vin->sequence = juint(item,"sequence"); + scriptPubKey = jbits256(item,"scriptPubKey"); + if ( bits256_nonz(scriptPubKey) > 0 ) + { + if ( (redeemstr= jstr(item,"redeemScript")) == 0 ) + { + vin->scriptlen = (int32_t)strlen(redeemstr); + if ( (vin->scriptlen & 1) != 0 ) + { + free_json(json); + return(clonestr("{\"error\":\"odd redeemScript length\"}")); + } + vin->scriptlen >>= 1; + vin->script = &space[len], len += vin->scriptlen; + } + } + } + } + vouts = (struct iguana_msgvout *)&space[len]; + if ( (array= jarray(&numvouts,json,"vouts")) != 0 ) + { + len += sizeof(*vouts) * numvouts; + memset(vouts,0,sizeof(*vouts) * numvouts); + //struct iguana_msgvout { uint64_t value; uint32_t pk_scriptlen; uint8_t *pk_script; }; + for (i=0; i 0 ) + { + + } + free_json(json); + } + if ( retjson == 0 ) + retjson = cJSON_Parse("{\"error\":\"couldnt create transaction\"}"); + return(jprint(retjson,1)); + } + + /* + if ( bp_key_init(&key) != 0 && bp_key_secret_set(&key,privkey,32) != 0 ) + { + if ( (T= calloc(1,sizeof(*T))) == 0 ) + return(0); + *T = *refT; vin = &T->inputs[redeemi]; + for (i=0; inuminputs; 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; isigs + 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)); + } + */ + + + /*static char *validateretstr(struct iguana_info *coin,char *coinaddr) + { + char *retstr,buf[512]; cJSON *json; + if ( iguana_addressvalidate(coin,coinaddr) < 0 ) + return(clonestr("{\"error\":\"invalid coin address\"}")); + sprintf(buf,"{\"agent\":\"ramchain\",\"coin\":\"%s\",\"method\":\"validate\",\"address\":\"%s\"}",coin->symbol,coinaddr); + if ( (json= cJSON_Parse(buf)) != 0 ) + retstr = ramchain_coinparser(coin,"validate",json); + else return(clonestr("{\"error\":\"internal error, couldnt parse validate\"}")); + free_json(json); + return(retstr); + } + + static char *validatepubkey(RPCARGS) + { + char *pubkeystr,coinaddr[128]; cJSON *retjson; + retjson = cJSON_CreateObject(); + if ( params[0] != 0 && (pubkeystr= jstr(params[0],0)) != 0 ) + { + if ( btc_coinaddr(coinaddr,coin->chain->pubval,pubkeystr) == 0 ) + return(validateretstr(coin,coinaddr)); + return(clonestr("{\"error\":\"cant convert pubkey\"}")); + } + return(clonestr("{\"error\":\"need pubkey\"}")); + }*/ #endif diff --git a/iguana/exchanges/bitcoin.c b/iguana/exchanges/bitcoin.c index 247187dd8..c673862a5 100755 --- a/iguana/exchanges/bitcoin.c +++ b/iguana/exchanges/bitcoin.c @@ -17,6 +17,233 @@ static const char base58_chars[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; +#define IGUANA_SCRIPT_NULL 0 +#define IGUANA_SCRIPT_76AC 1 +#define IGUANA_SCRIPT_76A988AC 2 +#define IGUANA_SCRIPT_P2SH 3 +#define IGUANA_SCRIPT_OPRETURN 4 +#define IGUANA_SCRIPT_3of3 5 +#define IGUANA_SCRIPT_2of3 6 +#define IGUANA_SCRIPT_1of3 7 +#define IGUANA_SCRIPT_2of2 8 +#define IGUANA_SCRIPT_1of2 9 +#define IGUANA_SCRIPT_MSIG 10 +#define IGUANA_SCRIPT_DATA 11 +#define IGUANA_SCRIPT_STRANGE 15 + +int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20]) +{ + script[n++] = SCRIPT_OP_DUP; + script[n++] = SCRIPT_OP_HASH160; + script[n++] = 20; memcpy(&script[n],rmd160,20); n += 20; + script[n++] = SCRIPT_OP_EQUALVERIFY; + script[n++] = SCRIPT_OP_CHECKSIG; + return(n); +} + +int32_t bitcoin_checklocktimeverify(uint8_t *script,int32_t n,uint32_t locktime) +{ + script[n++] = (locktime >> 24), script[n++] = (locktime >> 16), script[n++] = (locktime >> 8), script[n++] = locktime; + script[n++] = OP_CHECKLOCKTIMEVERIFY; + script[n++] = OP_DROP; + return(n); +} + +char *create_atomictx_cltvspend(char *scriptstr,uint8_t *rmd160A,uint8_t *rmd160B,uint32_t locktime) +{ + // OP_IF + // OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + // OP_ELSE + // OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG // standard spend + // OP_ENDIF + uint8_t hex[4096]; int32_t n = 0; + hex[n++] = SCRIPT_OP_IF; + n = bitcoin_checklocktimeverify(hex,n,locktime); + n = bitcoin_standardspend(hex,n,rmd160A); + hex[n++] = SCRIPT_OP_ELSE; + n = bitcoin_standardspend(hex,n,rmd160B); + hex[n++] = SCRIPT_OP_ENDIF; + init_hexbytes_noT(scriptstr,hex,n); + return(scriptstr); +} + +/*struct vin_signer { bits256 privkey; uint8_t siglen,sig[80],pubkey[65]; }; + + struct vin_info + { + struct iguana_msgvin vin; + int32_t M,N,validmask,voutlen; + struct vin_signer signers[16]; + uint8_t voutscript[IGUANA_MAXSCRIPTSIZE]; + };*/ + +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) +{ + uint8_t addrtype; char rmd160str[41]; int32_t scriptlen = 0; + if ( type == IGUANA_SCRIPT_76A988AC || type == IGUANA_SCRIPT_76AC ) + addrtype = coin->chain->pubtype; + else addrtype = coin->chain->p2shtype; + btc_convrmd160(coinaddr,addrtype,rmd160); + init_hexbytes_noT(rmd160str,rmd160,20); + //printf("addrtype.%d\n",addrtype); + switch ( type ) + { + case IGUANA_SCRIPT_NULL: + strcpy(asmstr,txi == 0 ? "coinbase" : "PoSbase"); + coinaddr[0] = 0; + break; + case IGUANA_SCRIPT_76AC: + sprintf(asmstr,"OP_DUP %s OP_CHECKSIG",rmd160str); + break; + case IGUANA_SCRIPT_76A988AC: + sprintf(asmstr,"OP_DUP OP_HASH160 %s OP_EQUALVERIFY OP_CHECKSIG",rmd160str); + break; + case IGUANA_SCRIPT_P2SH: + script[0] = SCRIPT_OP_HASH160, script[1] = 0x14; + memcpy(&script[2],rmd160,20); + script[22] = SCRIPT_OP_EQUAL; + sprintf(asmstr,"OP_HASH160 %s OP_EQUAL",coinaddr); + scriptlen = 23; + break; + case IGUANA_SCRIPT_OPRETURN: strcpy(asmstr,"OP_RETURN"); break; + case IGUANA_SCRIPT_3of3: strcpy(asmstr,"3 of 3 MSIG"); break; + case IGUANA_SCRIPT_2of3: strcpy(asmstr,"2 of 3 MSIG"); break; + case IGUANA_SCRIPT_1of3: strcpy(asmstr,"1 of 3 MSIG"); break; + case IGUANA_SCRIPT_2of2: strcpy(asmstr,"2 of 2 MSIG"); break; + case IGUANA_SCRIPT_1of2: strcpy(asmstr,"1 of 2 MSIG"); break; + case IGUANA_SCRIPT_MSIG: strcpy(asmstr,"NON-STANDARD MSIG"); break; + case IGUANA_SCRIPT_DATA: strcpy(asmstr,"DATA ONLY"); break; + case IGUANA_SCRIPT_STRANGE: strcpy(asmstr,"STRANGE SCRIPT"); break; + default: printf("unexpected script type\n"); break; + } + return(0); +} + +int32_t _iguana_calcrmd160(struct iguana_info *coin,uint8_t rmd160[20],uint8_t msigs160[16][20],int32_t *Mp,int32_t *nump,uint8_t *pk_script,int32_t pk_scriptlen,bits256 txid,int32_t vout) +{ + static uint8_t zero_rmd160[20]; + char hexstr[8192]; uint8_t sha256[32],*script,type; int32_t i,n,m,plen; + if ( nump != 0 ) + *nump = 0; + type = IGUANA_SCRIPT_STRANGE; + if ( pk_scriptlen == 0 ) + { + if ( zero_rmd160[0] == 0 ) + { + vcalc_sha256(0,sha256,pk_script,pk_scriptlen); // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 + calc_rmd160(0,zero_rmd160,sha256,sizeof(sha256)); // b472a266d0bd89c13706a4132ccfb16f7c3b9fcb + init_hexbytes_noT(hexstr,zero_rmd160,20); + char str[65]; printf("iguana_calcrmd160 zero len %s -> %s\n",bits256_str(str,*(bits256 *)sha256),hexstr); + } + memcpy(rmd160,zero_rmd160,sizeof(zero_rmd160)); + return(IGUANA_SCRIPT_NULL); + } + else if ( pk_script[0] == 0x6a ) + type = IGUANA_SCRIPT_OPRETURN; + else if ( pk_script[0] == 0x76 && pk_script[1] == 0xa9 && pk_script[2] == 20 && pk_script[pk_script[2]+3] == 0x88 && pk_script[pk_script[2]+4] == 0xac ) + { + //printf("IGUANA_SCRIPT_76A988AC plen.%d vs %d pk_scriptlen\n",pk_script[2]+4,pk_scriptlen); + // 76a9145f69cb73016264270dae9f65c51f60d0e4d6fd4488ac + //vcalc_sha256(0,sha256,&pk_script[3],pk_script[2]); + //calc_rmd160(0,rmd160,sha256,sizeof(sha256)); + memcpy(rmd160,&pk_script[3],20); + if ( (plen= pk_script[2]+5) < pk_scriptlen ) + { + while ( plen < pk_scriptlen ) + if ( pk_script[plen++] != 0x61 ) // nop + return(IGUANA_SCRIPT_STRANGE); + } + return(IGUANA_SCRIPT_76A988AC); + } + // 21035f1321ed17d387e4433b2fa229c53616057964af065f98bfcae2233c5108055eac + else if ( pk_script[0] > 0 && pk_script[0] < 76 && pk_script[pk_scriptlen-1] == 0xac && pk_script[0] == pk_scriptlen-2 ) + { + vcalc_sha256(0,sha256,&pk_script[1],pk_script[0]); + calc_rmd160(0,rmd160,sha256,sizeof(sha256)); + return(IGUANA_SCRIPT_76AC); + } + else if ( pk_script[0] == 0xa9 && pk_script[1] == 0x14 && pk_scriptlen == 23 && pk_script[22] == 0x87 ) + { + memcpy(rmd160,pk_script+2,20); + return(IGUANA_SCRIPT_P2SH); + } + else if ( pk_scriptlen > 34 && pk_script[pk_scriptlen-1] == 0xae && (n= pk_script[pk_scriptlen-2]) >= 0x51 && n <= 0x60 && (m= pk_script[0]) >= 0x51 && m <= n ) // m of n multisig + { + m -= 0x50, n -= 0x50; + if ( msigs160 != 0 && nump != 0 && *Mp != 0 ) + { + script = pk_script+1; + for (i=0; i> 24), script[n++] = (locktime >> 16), script[n++] = (locktime >> 8), script[n++] = locktime; - script[n++] = OP_CHECKLOCKTIMEVERIFY; - script[n++] = OP_DROP; - return(n); -} - -char *create_atomictx_cltvspend(char *scriptstr,uint8_t *rmd160A,uint8_t *rmd160B,uint32_t locktime) -{ - // OP_IF - // OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG - // OP_ELSE - // OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG // standard spend - // OP_ENDIF - uint8_t hex[4096]; int32_t n = 0; - hex[n++] = SCRIPT_OP_IF; - n = bitcoin_checklocktimeverify(hex,n,locktime); - n = bitcoin_standardspend(hex,n,rmd160A); - hex[n++] = SCRIPT_OP_ELSE; - n = bitcoin_standardspend(hex,n,rmd160B); - hex[n++] = SCRIPT_OP_ENDIF; - init_hexbytes_noT(scriptstr,hex,n); - return(scriptstr); -} - int32_t iguana_parsevoutobj(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_msgvout *vout,cJSON *voutobj) { int32_t len = 0; cJSON *skey; char *hexstr; @@ -337,7 +528,7 @@ int32_t iguana_parsevinobj(struct iguana_info *coin,uint8_t *serialized,int32_t vin->prev_hash = jbits256(vinobj,"txid"); vin->prev_vout = jint(vinobj,"vout"); if ( (sigjson= jobj(vinobj,"scriptSig")) != 0 ) - hexstr = jstr(sigjson,"hex"); + hexstr = jstr(sigjson,"redeemScript"); } if ( hexstr != 0 ) { @@ -358,10 +549,9 @@ int32_t iguana_parsevinobj(struct iguana_info *coin,uint8_t *serialized,int32_t //{"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) +cJSON *iguana_voutjson(struct iguana_info *coin,struct iguana_msgvout *vout,int32_t txi,bits256 txid) { // 035f1321ed17d387e4433b2fa229c53616057964af065f98bfcae2233c5108055e OP_CHECKSIG - static bits256 zero; char scriptstr[8192+1],coinaddr[65],asmstr[16384]; int32_t i,M,N,asmtype; uint8_t rmd160[20],msigs160[16][20],addrtype,space[8192]; cJSON *addrs,*skey,*json = cJSON_CreateObject(); @@ -370,7 +560,7 @@ cJSON *iguana_voutjson(struct iguana_info *coin,struct iguana_msgvout *vout,int3 //"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 ( (asmtype= iguana_calcrmd160(coin,rmd160,msigs160,&M,&N,vout->pk_script,vout->pk_scriptlen,zero)) >= 0 ) + if ( (asmtype= iguana_calcrmd160(coin,rmd160,msigs160,&M,&N,vout->pk_script,vout->pk_scriptlen,txid,txi)) >= 0 ) { skey = cJSON_CreateObject(); addrtype = iguana_scriptgen(coin,coinaddr,space,asmstr,rmd160,asmtype,txi); @@ -420,7 +610,7 @@ cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin) jaddstr(json,"txid",bits256_str(str,vin->prev_hash)); jaddnum(json,"vout",vout); sigjson = cJSON_CreateObject(); - jaddstr(sigjson,"hex",scriptstr); + jaddstr(sigjson,"redeemScript",scriptstr); jadd(json,"scriptSig",sigjson); } return(json); @@ -442,7 +632,7 @@ cJSON *iguana_txjson(struct iguana_info *coin,struct iguana_txid *tx,int32_t hei for (i=0; inumvouts; i++) { iguana_voutset(coin,space,asmstr,height,&vout,tx,i); - jaddi(vouts,iguana_voutjson(coin,&vout,i)); + jaddi(vouts,iguana_voutjson(coin,&vout,i,tx->txid)); } jadd(json,"vout",vouts); for (i=0; inumvins; i++) @@ -556,7 +746,7 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t rwflag,cJSON *json,uint8 { len += iguana_voutparse(rwflag,&serialized[len],&msg->vouts[i]); if ( array != 0 ) - jaddi(array,iguana_voutjson(coin,&msg->vouts[i],i)); + jaddi(array,iguana_voutjson(coin,&msg->vouts[i],i,*txidp)); } } else @@ -697,16 +887,6 @@ int32_t bitcoin_hashtype(uint8_t *script,int32_t scriptlen,uint8_t *pk_script,in return(SIGHASH_ALL); } -struct vin_signer { bits256 privkey; uint8_t siglen,sig[80],pubkey[65]; }; - -struct vin_info -{ - struct iguana_msgvin vin; - int32_t M,N,validmask,voutlen; - struct vin_signer signers[16]; - uint8_t voutscript[]; -}; - int32_t bitcoin_verifyvins(struct iguana_info *coin,int32_t *scriptlens,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxsize,bits256 myprivkey) { char txidstr[128],bigstr[2560],coinaddr[64],vpnstr[64],str[65],*pubkeys[16]; diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 295edadab..a55c2b5ae 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -18,6 +18,8 @@ #include "../crypto777/OS_portable.h" #include "SuperNET.h" +#define IGUANA_MAXSCRIPTSIZE 8192 + //#define IGUANA_DISABLEPEERS #define IGUANA_MAXCOINS 64 #define IGUANA_MAXDELAY_MILLIS (3600 * 1000) @@ -463,6 +465,16 @@ struct iguana_info struct iguana_waccount *wallet; }; +struct vin_signer { bits256 privkey; uint8_t siglen,sig[80],rmd160[20],pubkey[65]; }; + +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]; +}; + // peers int32_t iguana_verifypeer(struct iguana_info *coin,void *key,void *value,int32_t itemind,int32_t itemsize); int32_t iguana_peermetrics(struct iguana_info *coin); @@ -508,7 +520,7 @@ int64_t iguana_verifyaccount(struct iguana_info *coin,struct iguana_account *acc int32_t iguana_initramchain(struct iguana_info *coin,int32_t initialheight,int32_t mapflags,int32_t fullverify); void iguana_syncramchain(struct iguana_info *coin); //int32_t iguana_validateramchain(struct iguana_info *coin,int64_t *netp,uint64_t *creditsp,uint64_t *debitsp,int32_t height,struct iguana_block *block,int32_t hwmheight,struct iguana_prevdep *lp); -int32_t iguana_calcrmd160(struct iguana_info *coin,uint8_t rmd160[20],uint8_t msigs160[16][20],int32_t *Mp,int32_t *nump,uint8_t *pk_script,int32_t pk_scriptlen,bits256 debugtxid); +int32_t iguana_calcrmd160(struct iguana_info *coin,uint8_t rmd160[20],uint8_t msigs160[16][20],int32_t *Mp,int32_t *nump,uint8_t *pk_script,int32_t pk_scriptlen,bits256 debugtxid,int32_t vout); uint32_t iguana_updatescript(struct iguana_info *coin,uint32_t blocknum,uint32_t txidind,uint32_t spendind,uint32_t unspentind,uint64_t value,uint8_t *script,int32_t scriptlen,uint32_t sequence); void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *txdata,struct iguana_msgtx *txarray,struct iguana_msghdr *H,uint8_t *data,int32_t datalen); int32_t iguana_parseblock(struct iguana_info *coin,struct iguana_block *block,struct iguana_msgtx *tx,int32_t numtx); diff --git a/iguana/iguana_json.c b/iguana/iguana_json.c index 4d715c9ba..c4da8e73e 100755 --- a/iguana/iguana_json.c +++ b/iguana/iguana_json.c @@ -451,19 +451,12 @@ int32_t pretty_forms(char *fname,char *agentstr,char *suffix) char *SuperNET_htmlstr(char *fname,char *htmlstr,int32_t maxsize,char *agentstr) { - static int counter; - int32_t i,n,len,size = 0; cJSON *helpjson,*item,*array; char *str; FILE *fp = 0; + int32_t i,n,len,size = 0; long filesize; cJSON *helpjson,*item,*array; char *str; FILE *fp = 0; htmlstr[0] = 0; - if ( counter++ == 0 ) - { - pretty_forms("API.md",0,"md"); - printf("autocreate %s\n","API.md"); - } - if ( pretty_forms(fname,agentstr,"html") != 0 ) - { - //printf("%s\n",htmlstr); - return(htmlstr); - } + pretty_forms("API.md",0,"md"); + printf("autocreate %s\n","API.md"); + pretty_forms(fname,agentstr,"html"); + return(OS_filestr(&filesize,"index7778.html")); sprintf(htmlstr," SuperUGLY GUI> "); size = (int32_t)strlen(htmlstr); if ( (helpjson= SuperNET_helpjson()) != 0 ) diff --git a/iguana/iguana_pubkeys.c b/iguana/iguana_pubkeys.c index 687b9e99a..9c1d35627 100755 --- a/iguana/iguana_pubkeys.c +++ b/iguana/iguana_pubkeys.c @@ -894,311 +894,6 @@ int32_t iguana_sig(uint8_t *sig,int32_t maxsize,uint8_t *data,int32_t datalen,bi return(0); }*/ -#define IGUANA_SCRIPT_NULL 0 -#define IGUANA_SCRIPT_76AC 1 -#define IGUANA_SCRIPT_7688AC 2 -#define IGUANA_SCRIPT_P2SH 3 -#define IGUANA_SCRIPT_OPRETURN 4 -#define IGUANA_SCRIPT_3of3 5 -#define IGUANA_SCRIPT_2of3 6 -#define IGUANA_SCRIPT_1of3 7 -#define IGUANA_SCRIPT_2of2 8 -#define IGUANA_SCRIPT_1of2 9 -#define IGUANA_SCRIPT_MSIG 10 -#define IGUANA_SCRIPT_DATA 11 -#define IGUANA_SCRIPT_STRANGE 15 - -int32_t iguana_calcrmd160(struct iguana_info *coin,uint8_t rmd160[20],uint8_t msigs160[16][20],int32_t *Mp,int32_t *nump,uint8_t *pk_script,int32_t pk_scriptlen,bits256 debugtxid) -{ - static uint8_t zero_rmd160[20]; - char hexstr[8192]; uint8_t sha256[32],*script,type; int32_t i,n,m,plen; - if ( nump != 0 ) - *nump = 0; - type = IGUANA_SCRIPT_STRANGE; - if ( pk_scriptlen == 0 ) - { - if ( zero_rmd160[0] == 0 ) - { - vcalc_sha256(0,sha256,pk_script,pk_scriptlen); // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 - calc_rmd160(0,zero_rmd160,sha256,sizeof(sha256)); // b472a266d0bd89c13706a4132ccfb16f7c3b9fcb - init_hexbytes_noT(hexstr,zero_rmd160,20); - char str[65]; printf("iguana_calcrmd160 zero len %s -> %s\n",bits256_str(str,*(bits256 *)sha256),hexstr); - } - memcpy(rmd160,zero_rmd160,sizeof(zero_rmd160)); - return(IGUANA_SCRIPT_NULL); - } - else if ( pk_script[0] == 0x6a ) - type = IGUANA_SCRIPT_OPRETURN; - else if ( pk_script[0] == 0x76 && pk_script[1] == 0xa9 && pk_script[2] == 20 && pk_script[pk_script[2]+3] == 0x88 && pk_script[pk_script[2]+4] == 0xac ) - { - //printf("IGUANA_SCRIPT_7688AC plen.%d vs %d pk_scriptlen\n",pk_script[2]+4,pk_scriptlen); - // 76a9145f69cb73016264270dae9f65c51f60d0e4d6fd4488ac - //vcalc_sha256(0,sha256,&pk_script[3],pk_script[2]); - //calc_rmd160(0,rmd160,sha256,sizeof(sha256)); - memcpy(rmd160,&pk_script[3],20); - if ( (plen= pk_script[2]+5) < pk_scriptlen ) - { - while ( plen < pk_scriptlen ) - if ( pk_script[plen++] != 0x61 ) // nop - return(IGUANA_SCRIPT_STRANGE); - } - return(IGUANA_SCRIPT_7688AC); - } - // 21035f1321ed17d387e4433b2fa229c53616057964af065f98bfcae2233c5108055eac - else if ( pk_script[0] > 0 && pk_script[0] < 76 && pk_script[pk_scriptlen-1] == 0xac && pk_script[0] == pk_scriptlen-2 ) - { - vcalc_sha256(0,sha256,&pk_script[1],pk_script[0]); - calc_rmd160(0,rmd160,sha256,sizeof(sha256)); - return(IGUANA_SCRIPT_76AC); - } - else if ( pk_script[0] == 0xa9 && pk_script[1] == 0x14 && pk_scriptlen == 23 && pk_script[22] == 0x87 ) - { - memcpy(rmd160,pk_script+2,20); - return(IGUANA_SCRIPT_P2SH); - } - else if ( pk_scriptlen > 34 && pk_script[pk_scriptlen-1] == 0xae && (n= pk_script[pk_scriptlen-2]) >= 0x51 && n <= 0x60 && (m= pk_script[0]) >= 0x51 && m <= n ) // m of n multisig - { - m -= 0x50, n -= 0x50; - if ( msigs160 != 0 && nump != 0 && *Mp != 0 ) - { - script = pk_script+1; - for (i=0; ichain->pubtype; - else addrtype = coin->chain->p2shtype; - btc_convrmd160(coinaddr,addrtype,rmd160); - init_hexbytes_noT(rmd160str,rmd160,20); - //printf("addrtype.%d\n",addrtype); - switch ( type ) - { - case IGUANA_SCRIPT_NULL: - strcpy(asmstr,txi == 0 ? "coinbase" : "PoSbase"); - coinaddr[0] = 0; - break; - case IGUANA_SCRIPT_76AC: - sprintf(asmstr,"OP_DUP %s OP_CHECKSIG",rmd160str); - break; - case IGUANA_SCRIPT_7688AC: - sprintf(asmstr,"OP_DUP OP_HASH160 %s OP_EQUALVERIFY OP_CHECKSIG",rmd160str); - break; - case IGUANA_SCRIPT_P2SH: - script[0] = 0xa9, script[1] = 0x14; - memcpy(&script[2],rmd160,20); - script[22] = 0x87; - sprintf(asmstr,"OP_HASH160 %s OP_EQUAL",coinaddr); - scriptlen = 23; - break; - case IGUANA_SCRIPT_OPRETURN: strcpy(asmstr,"OP_RETURN"); break; - case IGUANA_SCRIPT_3of3: strcpy(asmstr,"3 of 3 MSIG"); break; - case IGUANA_SCRIPT_2of3: strcpy(asmstr,"2 of 3 MSIG"); break; - case IGUANA_SCRIPT_1of3: strcpy(asmstr,"1 of 3 MSIG"); break; - case IGUANA_SCRIPT_2of2: strcpy(asmstr,"2 of 2 MSIG"); break; - case IGUANA_SCRIPT_1of2: strcpy(asmstr,"1 of 2 MSIG"); break; - case IGUANA_SCRIPT_MSIG: strcpy(asmstr,"NON-STANDARD MSIG"); break; - case IGUANA_SCRIPT_DATA: strcpy(asmstr,"DATA ONLY"); break; - case IGUANA_SCRIPT_STRANGE: strcpy(asmstr,"STRANGE SCRIPT"); break; - default: printf("unexpected script type\n"); break; - } - return(0); -} - -char *iguana_txcreate(struct iguana_info *coin,uint8_t *space,int32_t maxlen,char *jsonstr) -{ - struct iguana_txid T; struct iguana_msgvin *vins,*vin; struct iguana_msgvout *vouts,*vout; - char *redeemstr; - cJSON *array,*json,*item,*retjson = 0; bits256 scriptPubKey; int32_t i,numvins,numvouts,len = 0; - if ( (json= cJSON_Parse(jsonstr)) != 0 ) - { - memset(&T,0,sizeof(T)); - if ( (T.version= juint(json,"version")) == 0 ) - T.version = 1; - if ( (T.locktime= juint(json,"locktime")) == 0 ) - T.locktime = 0xffffffff; - vins = (struct iguana_msgvin *)&space[len]; - if ( (array= jarray(&numvins,json,"vins")) != 0 ) - { - len += sizeof(*vins) * numvins; - memset(vins,0,sizeof(*vins) * numvins); - //struct iguana_msgvin { bits256 prev_hash; uint8_t *script; uint32_t prev_vout,scriptlen,sequence; }; - for (i=0; iprev_hash = jbits256(item,"txid"); - vin->prev_vout = juint(item,"vout"); - vin->sequence = juint(item,"sequence"); - scriptPubKey = jbits256(item,"scriptPubKey"); - if ( bits256_nonz(scriptPubKey) > 0 ) - { - if ( (redeemstr= jstr(item,"redeemScript")) == 0 ) - { - vin->scriptlen = (int32_t)strlen(redeemstr); - if ( (vin->scriptlen & 1) != 0 ) - { - free_json(json); - return(clonestr("{\"error\":\"odd redeemScript length\"}")); - } - vin->scriptlen >>= 1; - vin->script = &space[len], len += vin->scriptlen; - } - } - } - } - vouts = (struct iguana_msgvout *)&space[len]; - if ( (array= jarray(&numvouts,json,"vouts")) != 0 ) - { - len += sizeof(*vouts) * numvouts; - memset(vouts,0,sizeof(*vouts) * numvouts); - //struct iguana_msgvout { uint64_t value; uint32_t pk_scriptlen; uint8_t *pk_script; }; - for (i=0; i 0 ) - { - - } - free_json(json); - } - if ( retjson == 0 ) - retjson = cJSON_Parse("{\"error\":\"couldnt create transaction\"}"); - return(jprint(retjson,1)); -} - -/* -if ( bp_key_init(&key) != 0 && bp_key_secret_set(&key,privkey,32) != 0 ) -{ - if ( (T= calloc(1,sizeof(*T))) == 0 ) - return(0); - *T = *refT; vin = &T->inputs[redeemi]; - for (i=0; inuminputs; 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; isigs + 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)); - } -*/ - - -/*static char *validateretstr(struct iguana_info *coin,char *coinaddr) -{ - char *retstr,buf[512]; cJSON *json; - if ( iguana_addressvalidate(coin,coinaddr) < 0 ) - return(clonestr("{\"error\":\"invalid coin address\"}")); - sprintf(buf,"{\"agent\":\"ramchain\",\"coin\":\"%s\",\"method\":\"validate\",\"address\":\"%s\"}",coin->symbol,coinaddr); - if ( (json= cJSON_Parse(buf)) != 0 ) - retstr = ramchain_coinparser(coin,"validate",json); - else return(clonestr("{\"error\":\"internal error, couldnt parse validate\"}")); - free_json(json); - return(retstr); -} - -static char *validatepubkey(RPCARGS) -{ - char *pubkeystr,coinaddr[128]; cJSON *retjson; - retjson = cJSON_CreateObject(); - if ( params[0] != 0 && (pubkeystr= jstr(params[0],0)) != 0 ) - { - if ( btc_coinaddr(coinaddr,coin->chain->pubval,pubkeystr) == 0 ) - return(validateretstr(coin,coinaddr)); - return(clonestr("{\"error\":\"cant convert pubkey\"}")); - } - return(clonestr("{\"error\":\"need pubkey\"}")); -}*/ - char *makekeypair(struct iguana_info *coin) { struct iguana_waddress addr; char str[67]; cJSON *retjson = cJSON_CreateObject(); diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index df3944bcf..08f1b3ed6 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -375,7 +375,7 @@ uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,RAMCHAIN_FUNC,uin u = &U[unspentind]; if ( scriptlen == -20 ) memcpy(rmd160,script,20); - else type = iguana_calcrmd160(coin,rmd160,msigs160,&M,&N,script,scriptlen,txid); + else type = iguana_calcrmd160(coin,rmd160,msigs160,&M,&N,script,scriptlen,txid,vout); if ( ramchain->H.ROflag != 0 ) { //printf("%p U[%d] txidind.%d pkind.%d\n",u,unspentind,ramchain->txidind,pkind); diff --git a/iguana/iguana_rpc.c b/iguana/iguana_rpc.c index a70194bc4..aa4d9f90c 100755 --- a/iguana/iguana_rpc.c +++ b/iguana/iguana_rpc.c @@ -724,9 +724,8 @@ char *SuperNET_rpcparse(struct supernet_info *myinfo,char *retbuf,int32_t bufsiz *jsonflagp = 1; if ( (filestr= OS_filestr(&filesize,"index7778.html")) == 0 ) { - SuperNET_htmlstr("index7778.html",retbuf,bufsize,0); - filestr = OS_filestr(&filesize,"index7778.html"); - printf("created index7778.html size %ld\n",filesize); + if ( (filestr= SuperNET_htmlstr("index7778.html",retbuf,bufsize,0)) != 0 ) + printf("created index7778.html size %ld\n",strlen(filestr)); } return(filestr); } @@ -911,11 +910,14 @@ int32_t iguana_getheadersize(char *buf,int32_t recvlen) void iguana_rpcloop(void *args) { + static char *jsonbuf; uint16_t port; struct supernet_info *myinfo = args; int32_t recvlen,flag,bindsock,postflag,contentlen,sock,remains,numsent,jsonflag,hdrsize,len; - socklen_t clilen; char remoteaddr[64],jsonbuf[8192],*buf,*retstr,*space;//,*retbuf; ,n,i,m + socklen_t clilen; char remoteaddr[64],*buf,*retstr,*space;//,*retbuf; ,n,i,m struct sockaddr_in cli_addr; uint32_t ipbits,i,size = IGUANA_WIDTH*IGUANA_HEIGHT*16 + 512; port = IGUANA_RPCPORT; + if ( jsonbuf == 0 ) + jsonbuf = calloc(1,IGUANA_MAXPACKETSIZE); while ( (bindsock= iguana_socket(1,"127.0.0.1",port)) < 0 ) exit(-1); printf("iguana_rpcloop 127.0.0.1:%d bind sock.%d\n",port,bindsock); @@ -934,8 +936,8 @@ void iguana_rpcloop(void *args) expand_ipbits(remoteaddr,ipbits); //printf("RPC.%d for %x (%s)\n",sock,ipbits,ipaddr); //printf("%p got.(%s) from %s | usock.%d ready.%u dead.%u\n",addr,H.command,addr->ipaddr,addr->usock,addr->ready,addr->dead); - memset(jsonbuf,0,sizeof(jsonbuf)); - remains = (int32_t)(sizeof(jsonbuf) - 1); + memset(jsonbuf,0,IGUANA_MAXPACKETSIZE); + remains = (int32_t)(IGUANA_MAXPACKETSIZE - 1); buf = jsonbuf; recvlen = flag = 0; retstr = 0;