diff --git a/iguana/SuperNET.c b/iguana/SuperNET.c index bc2fbad94..c00fbf5d8 100755 --- a/iguana/SuperNET.c +++ b/iguana/SuperNET.c @@ -889,7 +889,7 @@ void SuperNET_parsepeers(struct supernet_info *myinfo,cJSON *array,int32_t n,int cJSON *SuperNET_rosettajson(bits256 privkey,int32_t showprivs) { - uint8_t rmd160[20],pub[33],flag = 0; uint64_t nxt64bits; bits256 pubkey; + uint8_t rmd160[20],pub[33]; uint64_t nxt64bits; bits256 pubkey; char str2[41],wifbuf[64],addr[64],str[128]; cJSON *retjson; pubkey = acct777_pubkey(privkey); nxt64bits = acct777_nxt64bits(pubkey); @@ -903,25 +903,25 @@ cJSON *SuperNET_rosettajson(bits256 privkey,int32_t showprivs) jaddstr(retjson,"btcpubkey",str); calc_OP_HASH160(str2,rmd160,str); jaddstr(retjson,"rmd160",str2); - if ( btc_coinaddr(addr,0,str) == 0 ) + if ( bitcoin_address(addr,0,pub,33) != 0 ) { jaddstr(retjson,"BTC",addr); - if ( flag != 0 ) + if ( showprivs != 0 ) { - btc_priv2wif(wifbuf,privkey.bytes,0x80); + btc_priv2wif(wifbuf,privkey.bytes,128); jaddstr(retjson,"BTCwif",wifbuf); } } - if ( btc_coinaddr(addr,60,str) == 0 ) + if ( bitcoin_address(addr,60,pub,33) != 0 ) { jaddstr(retjson,"BTCD",addr); - if ( flag != 0 ) + if ( showprivs != 0 ) { - btc_priv2wif(wifbuf,privkey.bytes,0xbc); + btc_priv2wif(wifbuf,privkey.bytes,188); jaddstr(retjson,"BTCDwif",wifbuf); } } - if ( flag != 0 ) + if ( showprivs != 0 ) jaddbits256(retjson,"privkey",privkey); return(retjson); } diff --git a/iguana/exchanges/bitcoin.c b/iguana/exchanges/bitcoin.c index 2e09edc09..d0d5da49a 100755 --- a/iguana/exchanges/bitcoin.c +++ b/iguana/exchanges/bitcoin.c @@ -960,10 +960,10 @@ cJSON *bitcoin_addinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32 } jaddbits256(item,"txid",txid); jaddnum(item,"vout",vout); - jaddnum(item,"sequenceid",sequenceid); + jaddnum(item,"sequence",sequenceid); jaddi(vins,item); jadd(txobj,"vin",vins); - //printf("addvin -> (%s)\n",jprint(txobj,0)); + printf("addvin -> (%s)\n",jprint(txobj,0)); return(txobj); } @@ -1066,7 +1066,8 @@ cJSON *iguana_signtx(struct iguana_info *coin,bits256 *txidp,char **signedtxp,st { if ( *signedtxp != 0 ) { - free_json(txobj); + if ( txobj != 0 ) + free_json(txobj); txobj = bitcoin_hex2json(coin,&txid,0,*signedtxp); free(*signedtxp); } @@ -1075,7 +1076,7 @@ cJSON *iguana_signtx(struct iguana_info *coin,bits256 *txidp,char **signedtxp,st memset(&V,0,sizeof(V)); for (j=0; jinputs[i].privkeys)/sizeof(*spend->inputs[i].privkeys); j++) { - if ( bits256_nonz(spend->inputs[i].privkeys[j]) > 0 ) + if ( bits256_nonz(spend->inputs[i].privkeys[j]) != 0 ) V.signers[j].privkey = spend->inputs[i].privkeys[j]; } if ( spend->inputs[i].spendlen > 0 ) diff --git a/iguana/exchanges/bitcoin.h b/iguana/exchanges/bitcoin.h index 28f6fd00e..7aca22435 100755 --- a/iguana/exchanges/bitcoin.h +++ b/iguana/exchanges/bitcoin.h @@ -63,20 +63,6 @@ struct bp_key { EC_KEY *k; }; -struct bitcoin_unspent -{ - bits256 txid,privkeys[16]; uint64_t value; int32_t vout,spendlen,p2shlen; uint32_t sequence; - uint8_t addrtype,rmd160[20],pubkey[65],spendscript[IGUANA_MAXSCRIPTSIZE],p2shscript[IGUANA_MAXSCRIPTSIZE]; -}; - -struct bitcoin_spend -{ - char changeaddr[64]; uint8_t change160[20]; - int32_t numinputs; - int64_t txfee,input_satoshis,satoshis,change; - struct bitcoin_unspent inputs[]; -}; - int32_t bitcoin_validaddress(struct iguana_info *coin,char *coinaddr); int32_t bitcoin_cltvscript(uint8_t p2shtype,char *ps2h_coinaddr,uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,char *senderaddr,char *otheraddr,uint8_t secret160[20],uint32_t locktime); int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr); diff --git a/iguana/iguana777.h b/iguana/iguana777.h index bd1776cb2..6576b5a95 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -528,6 +528,19 @@ struct vin_info char coinaddr[65]; uint8_t rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE],p2shscript[IGUANA_MAXSCRIPTSIZE]; }; +struct bitcoin_unspent +{ + bits256 txid,privkeys[16]; uint64_t value; int32_t vout,spendlen,p2shlen; uint32_t sequence; + uint8_t addrtype,rmd160[20],pubkey[65],spendscript[IGUANA_MAXSCRIPTSIZE],p2shscript[IGUANA_MAXSCRIPTSIZE]; +}; + +struct bitcoin_spend +{ + char changeaddr[64]; uint8_t change160[20]; + int32_t numinputs; + int64_t txfee,input_satoshis,satoshis,change; + struct bitcoin_unspent inputs[]; +}; // peers int32_t iguana_verifypeer(struct iguana_info *coin,void *key,void *value,int32_t itemind,int32_t itemsize); diff --git a/iguana/iguana_json.c b/iguana/iguana_json.c index aee5cfd64..000c1484a 100755 --- a/iguana/iguana_json.c +++ b/iguana/iguana_json.c @@ -134,6 +134,7 @@ cJSON *SuperNET_helpjson() #define IGUANA_HELP_SSDIS(agent,name,str,str2,amount,val,str3) array = helpjson(IGUANA_ARGS,#agent,#name,helparray5(cJSON_CreateArray(),helpitem(#str,"string"),helpitem(#str2,"string"),helpitem(#amount,"float"),helpitem(#val,"int"),helpitem(#str3,"string"))) #define IGUANA_HELP_SSDISS(agent,name,str,str2,amount,val,str3,str4) array = helpjson(IGUANA_ARGS,#agent,#name,helparray6(cJSON_CreateArray(),helpitem(#str,"string"),helpitem(#str2,"string"),helpitem(#amount,"float"),helpitem(#val,"int"),helpitem(#str3,"string"),helpitem(#str4,"string"))) #define IGUANA_HELP_SAIS(agent,name,str,obj,val,str2) array = helpjson(IGUANA_ARGS,#agent,#name,helparray4(cJSON_CreateArray(),helpitem(#str,"string"),helpitem(#obj,"array"),helpitem(#val,"int"),helpitem(#str2,"string"))) +#define IGUANA_HELP_SAOS(agent,name,str,obj,obj2,str2) array = helpjson(IGUANA_ARGS,#agent,#name,helparray4(cJSON_CreateArray(),helpitem(#str,"string"),helpitem(#obj,"array"),helpitem(#obj2,"object"),helpitem(#str2,"string"))) #define IGUANA_HELP_SDSS(agent,name,str,amount,str2,str3) array = helpjson(IGUANA_ARGS,#agent,#name,helparray4(cJSON_CreateArray(),helpitem(#str,"string"),helpitem(#amount,"float"),helpitem(#str2,"string"),helpitem(#str3,"string"))) #define IGUANA_HELP_SHI_SDSD_II_SSSSSS(agent,name,str,hash,val,str2,amount,str3,amount2,val2,val3,str4,str5,str6,str7,str8,str9) array = helpjson(IGUANA_ARGS,#agent,#name,helparray15(cJSON_CreateArray(),helpitem(#str,"string"),helpitem(#hash,"hash"),helpitem(#val,"int"),helpitem(#str2,"string"),helpitem(#amount,"float"),helpitem(#str3,"string"),helpitem(#amount2,"float"),helpitem(#val2,"int"),helpitem(#val3,"int"),helpitem(#str4,"string"),helpitem(#str5,"string"),helpitem(#str6,"string"),helpitem(#str7,"string"),helpitem(#str8,"string"),helpitem(#str9,"string"))) @@ -182,6 +183,7 @@ cJSON *SuperNET_helpjson() #define STRING_AND_TWO_DOUBLES IGUANA_HELP_SDD #define P2SH_SPENDAPI IGUANA_HELP_SHI_SDSD_II_SSSSSS #define ARRAY_OBJ_INT IGUANA_HELP_AOI +#define STRING_ARRAY_OBJ_STRING IGUANA_HELP_SAOS #include "../includes/iguana_apideclares.h" @@ -935,6 +937,7 @@ char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,c #define IGUANA_DISPATCH_SSDIS(agent,name,str,str2,amount,val,str3) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jstr(json,#str2),jdouble(json,#amount),juint(json,#val),jstr(json,#str3))) #define IGUANA_DISPATCH_SSDISS(agent,name,str,str2,amount,val,str3,str4) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jstr(json,#str2),jdouble(json,#amount),juint(json,#val),jstr(json,#str3),jstr(json,#str4))) #define IGUANA_DISPATCH_SAIS(agent,name,str,array,val,str2) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jobj(json,#array),juint(json,#val),jstr(json,#str2))) +#define IGUANA_DISPATCH_SAOS(agent,name,str,array,object,str2) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jobj(json,#array),jobj(json,#object),jstr(json,#str2))) #define IGUANA_DISPATCH_SDSS(agent,name,str,amount,str2,str3) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jdouble(json,#amount),jstr(json,#str2),jstr(json,#str3))) #define IGUANA_DISPATCH_SHI_SDSD_II_SSSSSS(agent,name,str,hash,val,str2,amount,str3,amount2,val2,val3,str4,str5,str6,str7,str8,str9) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jbits256(json,#hash),jint(json,#val),jstr(json,#str2),jdouble(json,#amount),jstr(json,#str3),jdouble(json,#amount2),juint(json,#val2),juint(json,#val3),jstr(json,#str4),jstr(json,#str5),jstr(json,#str6),jstr(json,#str7),jstr(json,#str8),jstr(json,#str9))) @@ -983,6 +986,7 @@ char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,c #define STRING_AND_TWO_DOUBLES IGUANA_DISPATCH_SDD #define P2SH_SPENDAPI IGUANA_DISPATCH_SHI_SDSD_II_SSSSSS #define ARRAY_OBJ_INT IGUANA_DISPATCH_AOI +#define STRING_ARRAY_OBJ_STRING IGUANA_DISPATCH_SAOS #include "../includes/iguana_apideclares.h" //#undef IGUANA_ARGS diff --git a/iguana/iguana_rpc.c b/iguana/iguana_rpc.c index 45984d670..1632efd37 100755 --- a/iguana/iguana_rpc.c +++ b/iguana/iguana_rpc.c @@ -495,7 +495,7 @@ static char *decodescript(RPCARGS) static char *signrawtransaction(RPCARGS) { - return(sglue3(0,CALLGLUE,"bitcoinrpc","signrawtransaction","rawtx",params[0],"vins",params[1],"privkeys",params[2])); + return(sglue4(0,CALLGLUE,"bitcoinrpc","signrawtransaction","rawtx",params[0],"vins",params[1],"privkeys",params[2],"sighash",params[3])); } static char *sendrawtransaction(RPCARGS) diff --git a/iguana/iguana_wallet.c b/iguana/iguana_wallet.c index 129023331..1d691c37f 100755 --- a/iguana/iguana_wallet.c +++ b/iguana/iguana_wallet.c @@ -267,14 +267,17 @@ char *jsuccess() bits256 iguana_str2priv(struct iguana_info *coin,char *str) { bits256 privkey; int32_t ind,n; uint8_t addrtype; struct iguana_waccount *wacct; - n = (int32_t)strlen(str) >> 1; memset(&privkey,0,sizeof(privkey)); - if ( n == sizeof(bits256) && is_hexstr(str,sizeof(bits256)) > 0 ) - decode_hex(privkey.bytes,sizeof(privkey),str); - else if ( btc_wif2priv(&addrtype,privkey.bytes,str) != sizeof(bits256) ) + if ( str != 0 ) { - if ( (wacct= iguana_waddressfind(coin,&ind,str)) != 0 ) - privkey = wacct->waddrs[ind].privkey; + n = (int32_t)strlen(str) >> 1; + if ( n == sizeof(bits256) && is_hexstr(str,sizeof(bits256)) > 0 ) + decode_hex(privkey.bytes,sizeof(privkey),str); + else if ( btc_wif2priv(&addrtype,privkey.bytes,str) != sizeof(bits256) ) + { + if ( (wacct= iguana_waddressfind(coin,&ind,str)) != 0 ) + privkey = wacct->waddrs[ind].privkey; + } } return(privkey); } diff --git a/iguana/ramchain_api.c b/iguana/ramchain_api.c index 10eb77e3e..b0d443f4f 100755 --- a/iguana/ramchain_api.c +++ b/iguana/ramchain_api.c @@ -397,7 +397,7 @@ ARRAY_OBJ_INT(bitcoinrpc,createrawtransaction,vins,vouts,locktime) { item = jitem(vins,i); p2shlen = scriptlen = 0; - if ( (str= jstr(item,"scriptPubKey")) != 0 ) + if ( (str= jstr(item,"scriptPubKey")) != 0 || (str= jstr(item,"scriptPubkey")) != 0 ) { scriptlen = (int32_t)strlen(str) >> 1; decode_hex(script,scriptlen,str); @@ -488,9 +488,59 @@ ARRAY_OBJ_INT(bitcoinrpc,createrawtransaction,vins,vouts,locktime) return(jprint(retjson,1)); } -STRING_AND_TWOARRAYS(bitcoinrpc,signrawtransaction,rawtx,vins,privkeys) +/*struct bitcoin_unspent { - cJSON *retjson = cJSON_CreateObject(); + bits256 txid,privkeys[16]; uint64_t value; int32_t vout,spendlen,p2shlen; uint32_t sequence; + uint8_t addrtype,rmd160[20],pubkey[65],spendscript[IGUANA_MAXSCRIPTSIZE],p2shscript[IGUANA_MAXSCRIPTSIZE]; +}; + +struct bitcoin_spend +{ + char changeaddr[64]; uint8_t change160[20]; + int32_t numinputs; + int64_t txfee,input_satoshis,satoshis,change; + struct bitcoin_unspent inputs[]; +};*/ + +STRING_ARRAY_OBJ_STRING(bitcoinrpc,signrawtransaction,rawtx,vins,privkeys,sighash) +{ + bits256 txid; char *privkeystr,*signedtx = 0; bits256 privkey; int32_t i,n,numinputs = 1; struct bitcoin_spend *spend; cJSON *txobj=0,*item,*retjson = cJSON_CreateObject(); + //printf("rawtx.(%s) vins.(%s) privkeys.(%s) sighash.(%s)\n",rawtx,jprint(vins,0),jprint(privkeys,0),sighash); + if ( sighash == 0 || sighash[0] == 0 ) + sighash = "ALL"; + if ( strcmp(sighash,"ALL") != 0 ) + jaddstr(retjson,"error","only sighash all supported for now"); + else + { + // need to mix and match privkeys with inputs[i] + signedtx = clonestr(rawtx); + if ( (numinputs= cJSON_GetArraySize(vins)) > 0 && (n= cJSON_GetArraySize(privkeys)) > 0 ) + { + spend = calloc(1,sizeof(*spend) + (sizeof(*spend->inputs) * numinputs)); + spend->numinputs = numinputs; + for (i=0; iinputs[0].privkeys[i] = privkey; + //if ( i < numinputs ) + // spend->inputs[i].privkeys[0] = privkey; + char str2[65]; printf("privkey.%s <- %s\n",bits256_str(str2,privkey),privkeystr); + } + } + txobj = iguana_signtx(coin,&txid,&signedtx,spend,txobj); + free(spend); + free_json(txobj); + if ( signedtx != 0 ) + { + jaddstr(retjson,"result",signedtx); + free(signedtx); + } + } + } return(jprint(retjson,1)); } diff --git a/includes/iguana_apideclares.h b/includes/iguana_apideclares.h index a099f4b62..9c8bd7514 100755 --- a/includes/iguana_apideclares.h +++ b/includes/iguana_apideclares.h @@ -26,13 +26,12 @@ HASH_ARG(bitcoinrpc,gettransaction,txid); STRING_ARG(bitcoinrpc,decodescript,script); STRING_ARG(bitcoinrpc,decoderawtransaction,rawtx); -ARRAY_OBJ_INT(bitcoinrpc,createrawtransaction,vins,vouts,locktime); // -STRING_AND_TWOARRAYS(bitcoinrpc,signrawtransaction,rawtx,vins,privkeys); // +ARRAY_OBJ_INT(bitcoinrpc,createrawtransaction,vins,vouts,locktime); +STRING_ARRAY_OBJ_STRING(bitcoinrpc,signrawtransaction,rawtx,vins,privkeys,sighash); // STRING_AND_INT(bitcoinrpc,sendrawtransaction,rawtx,allowhighfees); // HASH_AND_TWOINTS(bitcoinrpc,gettxout,txid,vout,mempool); TWOINTS_AND_ARRAY(bitcoinrpc,listunspent,minconf,maxconf,array); -HASH_AND_TWOINTS(bitcoinrpc,listsinceblock,blockhash,target,flag); // SS_D_I_S(bitcoinrpc,move,fromaccount,toaccount,amount,minconf,comment); // SS_D_I_SS(bitcoinrpc,sendfrom,fromaccount,toaddress,amount,minconf,comment,comment2); // @@ -71,6 +70,7 @@ TWO_STRINGS(bitcoinrpc,setaccount,address,account); TWO_STRINGS(bitcoinrpc,signmessage,address,message); // THREE_STRINGS(bitcoinrpc,verifymessage,address,sig,message); // +HASH_AND_TWOINTS(bitcoinrpc,listsinceblock,blockhash,target,flag); // ZERO_ARGS(bitcoinrpc,gettxoutsetinfo); INT_AND_ARRAY(bitcoinrpc,lockunspent,flag,array); ZERO_ARGS(bitcoinrpc,listlockunspent); diff --git a/includes/iguana_apidefs.h b/includes/iguana_apidefs.h index aafd3db9e..2e37feb8b 100755 --- a/includes/iguana_apidefs.h +++ b/includes/iguana_apidefs.h @@ -47,6 +47,7 @@ #define IGUANA_CFUNC_SSDIS(agent,name,str,str2,amount,val,str3) char *agent ## _ ## name(IGUANA_ARGS,char *str,char *str2,double amount,int32_t val,char *str3) #define IGUANA_CFUNC_SSDISS(agent,name,str,str2,amount,val,str3,str4) char *agent ## _ ## name(IGUANA_ARGS,char *str,char *str2,double amount,int32_t val,char *str3,char *str4) #define IGUANA_CFUNC_SAIS(agent,name,str,array,val,str2) char *agent ## _ ## name(IGUANA_ARGS,char *str,cJSON *array,int32_t val,char *str2) +#define IGUANA_CFUNC_SAOS(agent,name,str,array,object,str2) char *agent ## _ ## name(IGUANA_ARGS,char *str,cJSON *array,cJSON *object,char *str2) #define IGUANA_CFUNC_SDSS(agent,name,str,amount,str2,str3) char *agent ## _ ## name(IGUANA_ARGS,char *str,double amount,char *str2,char *str3) // API functions @@ -69,6 +70,7 @@ #define STRING_AND_TWOARRAYS IGUANA_CFUNC_SAA #define TWO_ARRAYS IGUANA_CFUNC_AA #define ARRAY_OBJ_INT IGUANA_CFUNC_AOI +#define STRING_ARRAY_OBJ_STRING IGUANA_CFUNC_SAOS #define INT_AND_ARRAY IGUANA_CFUNC_IA #define INT_ARRAY_STRING IGUANA_CFUNC_IAS #define SS_D_I_S IGUANA_CFUNC_SSDIS diff --git a/includes/iguana_apiundefs.h b/includes/iguana_apiundefs.h index cb3c4d972..c69c0f2db 100755 --- a/includes/iguana_apiundefs.h +++ b/includes/iguana_apiundefs.h @@ -42,6 +42,7 @@ #undef TWO_STRINGS_AND_TWO_DOUBLES #undef STRING_AND_TWO_DOUBLES #undef P2SH_SPENDAPI +#undef STRING_ARRAY_OBJ_STRING #undef IGUANA_ARGS #undef IGUANA_CALLARGS