diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index 8991d9869..72ef9f02b 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -839,6 +839,25 @@ char *get_cJSON_fieldname(cJSON *obj) return((char *)""); } +int32_t jnum(cJSON *obj,char *field) +{ + char *str; int32_t polarity = 1; + if ( field != 0 ) + obj = jobj(obj,field); + if ( obj != 0 ) + { + if ( is_cJSON_Number(obj) != 0 ) + return(obj->valuedouble); + else if ( is_cJSON_String(obj) != 0 && (str= jstr(obj,0)) != 0 ) + { + if ( str[0] == '-' ) + polarity = -1, str++; + return(polarity * (int32_t)calc_nxt64bits(str)); + } + } + return(0); +} + void ensure_jsonitem(cJSON *json,char *field,char *value) { cJSON *obj = cJSON_GetObjectItem(json,field); diff --git a/crypto777/crypto777.sources b/crypto777/crypto777.sources index 0b8882e8a..a690a844a 100644 --- a/crypto777/crypto777.sources +++ b/crypto777/crypto777.sources @@ -1,11 +1,4 @@ -JPEG_SRCS := ../crypto777/jpeg/jaricom.c ../crypto777/jpeg/jcapimin.c ../crypto777/jpeg/jcapistd.c ../crypto777/jpeg/jcarith.c ../crypto777/jpeg/jccoefct.c ../crypto777/jpeg/jccolor.c \ - ../crypto777/jpeg/jcdctmgr.c ../crypto777/jpeg/jchuff.c ../crypto777/jpeg/jcinit.c ../crypto777/jpeg/jcmainct.c ../crypto777/jpeg/jcmarker.c ../crypto777/jpeg/jcmaster.c \ - ../crypto777/jpeg/jcomapi.c ../crypto777/jpeg/jcparam.c ../crypto777/jpeg/jcprepct.c ../crypto777/jpeg/jcsample.c ../crypto777/jpeg/jctrans.c ../crypto777/jpeg/jdapimin.c \ - ../crypto777/jpeg/jdapistd.c ../crypto777/jpeg/jdarith.c ../crypto777/jpeg/jdatadst.c ../crypto777/jpeg/jdatasrc.c ../crypto777/jpeg/jdcoefct.c ../crypto777/jpeg/jdcolor.c \ - ../crypto777/jpeg/jddctmgr.c ../crypto777/jpeg/jdhuff.c ../crypto777/jpeg/jdinput.c ../crypto777/jpeg/jdmainct.c ../crypto777/jpeg/jdmarker.c ../crypto777/jpeg/jdmaster.c \ - ../crypto777/jpeg/jdmerge.c ../crypto777/jpeg/jdpostct.c ../crypto777/jpeg/jdsample.c ../crypto777/jpeg/jdtrans.c ../crypto777/jpeg/jerror.c ../crypto777/jpeg/jfdctflt.c \ - ../crypto777/jpeg/jfdctfst.c ../crypto777/jpeg/jfdctint.c ../crypto777/jpeg/jidctflt.c ../crypto777/jpeg/jidctfst.c ../crypto777/jpeg/jidctint.c ../crypto777/jpeg/jquant1.c \ - ../crypto777/jpeg/jquant2.c ../crypto777/jpeg/jutils.c ../crypto777/jpeg/jmemmgr.c ../crypto777/jpeg/jmemnobs.c +JPEG_SRCS := ../crypto777/jpeg/jaricom.c ../crypto777/jpeg/jcapimin.c ../crypto777/jpeg/jcapistd.c ../crypto777/jpeg/jcarith.c ../crypto777/jpeg/jccoefct.c ../crypto777/jpeg/jccolor.c ../crypto777/jpeg/jcdctmgr.c ../crypto777/jpeg/jchuff.c ../crypto777/jpeg/jcinit.c ../crypto777/jpeg/jcmainct.c ../crypto777/jpeg/jcmarker.c ../crypto777/jpeg/jcmaster.c ../crypto777/jpeg/jcomapi.c ../crypto777/jpeg/jcparam.c ../crypto777/jpeg/jcprepct.c ../crypto777/jpeg/jcsample.c ../crypto777/jpeg/jctrans.c ../crypto777/jpeg/jdapimin.c ../crypto777/jpeg/jdapistd.c ../crypto777/jpeg/jdarith.c ../crypto777/jpeg/jdatadst.c ../crypto777/jpeg/jdatasrc.c ../crypto777/jpeg/jdcoefct.c ../crypto777/jpeg/jdcolor.c ../crypto777/jpeg/jddctmgr.c ../crypto777/jpeg/jdhuff.c ../crypto777/jpeg/jdinput.c ../crypto777/jpeg/jdmainct.c ../crypto777/jpeg/jdmarker.c ../crypto777/jpeg/jdmaster.c ../crypto777/jpeg/jdmerge.c ../crypto777/jpeg/jdpostct.c ../crypto777/jpeg/jdsample.c ../crypto777/jpeg/jdtrans.c ../crypto777/jpeg/jerror.c ../crypto777/jpeg/jfdctflt.c ../crypto777/jpeg/jfdctfst.c ../crypto777/jpeg/jfdctint.c ../crypto777/jpeg/jidctflt.c ../crypto777/jpeg/jidctfst.c ../crypto777/jpeg/jidctint.c ../crypto777/jpeg/jquant1.c ../crypto777/jpeg/jquant2.c ../crypto777/jpeg/jutils.c ../crypto777/jpeg/jmemmgr.c ../crypto777/jpeg/jmemnobs.c CRYPTO777_SRCS := ../crypto777/ccgi.c ../crypto777/cJSON.c ../crypto777/iguana_utils.c ../crypto777/OS_nonportable.c ../crypto777/curve25519-donna.c ../crypto777/inet.c ../crypto777/OS_portable.c ../crypto777/curve25519.c ../crypto777/libgfshare.c ../crypto777/OS_time.c ../crypto777/hmac_sha512.c ../crypto777/ramcoder.c ../crypto777/SaM.c ../crypto777/iguana_OS.c ../crypto777/iguana_serdes.c $(JPEG_SRCS) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 8b17adcb8..d5e5ea926 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -682,5 +682,61 @@ int32_t iguana_launchcoin(char *symbol,cJSON *json); int32_t iguana_jsonQ(); int32_t is_bitcoinrpc(char *method); char *iguana_bitcoinRPC(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr); +cJSON *iguana_pubkeyjson(struct iguana_info *coin,char *pubkeystr); + + +char *iguana_listsinceblock(struct supernet_info *myinfo,struct iguana_info *coin,bits256 blockhash,int32_t target); +char *iguana_getreceivedbyaccount(struct supernet_info *myinfo,struct iguana_info *coin,char *account,int32_t minconf); +char *iguana_listreceivedbyaccount(struct supernet_info *myinfo,struct iguana_info *coin,char *account,int32_t includeempty); + +char *iguana_getaccountaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *account); +char *iguana_setaccount(struct supernet_info *myinfo,struct iguana_info *coin,char *account); +char *iguana_getaccount(struct supernet_info *myinfo,struct iguana_info *coin,char *account); +char *iguana_getaddressesbyaccount(struct supernet_info *myinfo,struct iguana_info *coin,char *account); +char *iguana_listaddressgroupings(struct supernet_info *myinfo,struct iguana_info *coin); +char *iguana_getbalance(struct supernet_info *myinfo,struct iguana_info *coin,char *account,int32_t minconf); +char *iguana_listaccounts(struct supernet_info *myinfo,struct iguana_info *coin,int32_t minconf); + +char *iguana_move(struct supernet_info *myinfo,struct iguana_info *coin,char *fromaccount,char *toaccount,double amount,int32_t minconf,char *comment); +char *iguana_sendfrom(struct supernet_info *myinfo,struct iguana_info *coin,char *fromaccount,char *toaddress,double amount,int32_t minconf,char *comment,char *comment2); +char *iguana_sendmany(struct supernet_info *myinfo,struct iguana_info *coin,char *fromaccount,cJSON *payments,int32_t minconf,char *comment); + +char *iguana_dumpprivkey(struct supernet_info *myinfo,struct iguana_info *coin,char *address); +char *iguana_importprivkey(struct supernet_info *myinfo,struct iguana_info *coin,char *wip); +char *iguana_dumpwallet(struct supernet_info *myinfo,struct iguana_info *coin); +char *iguana_importwallet(struct supernet_info *myinfo,struct iguana_info *coin,char *wallet); +char *iguana_walletpassphrase(struct supernet_info *myinfo,struct iguana_info *coin,char *passphrase,int32_t timeout); +char *iguana_walletpassphrasechange(struct supernet_info *myinfo,struct iguana_info *coin,char *oldpassphrase,char *newpassphrase); +char *iguana_walletlock(struct supernet_info *myinfo,struct iguana_info *coin); +char *iguana_encryptwallet(struct supernet_info *myinfo,struct iguana_info *coin,char *passphrase); +char *iguana_checkwallet(struct supernet_info *myinfo,struct iguana_info *coin); +char *iguana_repairwallet(struct supernet_info *myinfo,struct iguana_info *coin); +char *iguana_backupwallet(struct supernet_info *myinfo,struct iguana_info *coin,char *filename); + +char *iguana_signmessage(struct supernet_info *myinfo,struct iguana_info *coin,char *address,char *message); +char *iguana_verifymessage(struct supernet_info *myinfo,struct iguana_info *coin,char *address,char *sig,char *message); +char *iguana_getnewaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *account); +char *iguana_makekeypair(struct supernet_info *myinfo,struct iguana_info *coin); +char *iguana_vanitygen(struct supernet_info *myinfo,struct iguana_info *coin,char *vanity); +char *iguana_createmultisig(struct supernet_info *myinfo,struct iguana_info *coin,int32_t M,cJSON *pubkeys,char *account); + +char *iguana_getrawchangeaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *account); +char *iguana_settxfee(struct supernet_info *myinfo,struct iguana_info *coin,double amount); +char *iguana_listtransactions(struct supernet_info *myinfo,struct iguana_info *coin,char *account,int32_t count,int32_t from); +char *iguana_listunspent(struct supernet_info *myinfo,struct iguana_info *coin,int32_t minconf,int32_t maxconf); +char *iguana_lockunspent(struct supernet_info *myinfo,struct iguana_info *coin,char *filename); +char *iguana_listlockunspent(struct supernet_info *myinfo,struct iguana_info *coin,char *unlock,cJSON *array); +char *iguana_gettxout(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid,int32_t vout,int32_t mempool); +char *iguana_gettxoutsetinfo(struct supernet_info *myinfo,struct iguana_info *coin); +char *iguana_getrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid,int32_t verbose); +char *iguana_createrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *vins,cJSON *vouts); +char *iguana_decoderawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *rawtx); +char *iguana_decodescript(struct supernet_info *myinfo,struct iguana_info *coin,char *script); +char *iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *rawtx,cJSON *vins,cJSON *privkeys); +char *iguana_sendrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *rawtx); +char *iguana_sendtoaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *address,double amount,char *comment,char *comment2); +char *iguana_getreceivedbyaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *address,int32_t minconf); +char *iguana_listreceivedbyaddress(struct supernet_info *myinfo,struct iguana_info *coin,int32_t minconf,int32_t includeempty); + #endif diff --git a/iguana/iguana_json.c b/iguana/iguana_json.c index 5ca700b8b..dd5d84aee 100755 --- a/iguana/iguana_json.c +++ b/iguana/iguana_json.c @@ -88,10 +88,18 @@ cJSON *iguana_peersjson(struct iguana_info *coin,int32_t addronly) char *iguana_coinjson(struct iguana_info *coin,char *method,cJSON *json) { - int32_t i,max,retval; struct iguana_peer *addr; char *ipaddr; cJSON *retjson = 0; + int32_t i,max,retval,num=0; char buf[1024]; struct iguana_peer *addr; char *ipaddr; cJSON *retjson = 0; //printf("iguana_coinjson(%s)\n",jprint(json,0)); if ( strcmp(method,"peers") == 0 ) return(jprint(iguana_peersjson(coin,0),1)); + else if ( strcmp(method,"getconnectioncount") == 0 ) + { + for (i=0; ipeers.active)/sizeof(*coin->peers.active); i++) + if ( coin->peers.active[i].usock >= 0 ) + num++; + sprintf(buf,"{\"result\":\"%d\"}",num); + return(clonestr(buf)); + } else if ( strcmp(method,"addnode") == 0 ) { if ( (ipaddr= jstr(json,"ipaddr")) != 0 ) @@ -100,6 +108,30 @@ char *iguana_coinjson(struct iguana_info *coin,char *method,cJSON *json) return(clonestr("{\"result\":\"addnode submitted\"}")); } else return(clonestr("{\"error\":\"addnode needs ipaddr\"}")); } + else if ( strcmp(method,"removenode") == 0 ) + { + if ( (ipaddr= jstr(json,"ipaddr")) != 0 ) + { + for (i=0; ipeers.active[i].ipaddr,ipaddr) == 0 ) + { + coin->peers.active[i].rank = 0; + coin->peers.active[i].dead = (uint32_t)time(NULL); + return(clonestr("{\"result\":\"node marked as dead\"}")); + } + } + return(clonestr("{\"result\":\"node wasnt active\"}")); + } else return(clonestr("{\"error\":\"removenode needs ipaddr\"}")); + } + else if ( strcmp(method,"oneshot") == 0 ) + { + if ( (ipaddr= jstr(json,"ipaddr")) != 0 ) + { + iguana_possible_peer(coin,ipaddr); + return(clonestr("{\"result\":\"addnode submitted\"}")); + } else return(clonestr("{\"error\":\"addnode needs ipaddr\"}")); + } else if ( strcmp(method,"nodestatus") == 0 ) { if ( (ipaddr= jstr(json,"ipaddr")) != 0 ) @@ -131,6 +163,14 @@ char *iguana_coinjson(struct iguana_info *coin,char *method,cJSON *json) jaddstr(retjson,"coin",coin->symbol); return(jprint(retjson,1)); } + else if ( strcmp(method,"getrawmempool") == 0 ) + { + return(clonestr("{\"result\":\"no rampool yet\"}")); + } + else if ( strcmp(method,"sendalert") == 0 ) + { + return(clonestr("{\"result\":\"no sendalert yet\"}")); + } else if ( strcmp(method,"startcoin") == 0 ) { coin->active = 1; @@ -250,3 +290,608 @@ char *iguana_parser(struct supernet_info *myinfo,char *method,cJSON *json,char * return(clonestr("{\"result\":\"stub processed generic json\"}")); } +struct iguana_txid *iguana_blocktx(struct iguana_info *coin,struct iguana_txid *tx,struct iguana_block *block,int32_t i) +{ + struct iguana_bundle *bp; uint32_t txidind; + if ( i >= 0 && i < block->RO.txn_count ) + { + if ( block->height >= 0 ) // + { + if ( (bp= coin->bundles[block->hdrsi]) != 0 ) + { + if ( (txidind= block->RO.firsttxidind) > 0 )//bp->firsttxidinds[block->bundlei]) > 0 ) + { + if ( iguana_bundletx(coin,bp,block->bundlei,tx,txidind+i) == tx ) + return(tx); + printf("error getting txidind.%d + i.%d from hdrsi.%d\n",txidind,i,block->hdrsi); + return(0); + } else printf("iguana_blocktx null txidind\n"); + } else printf("iguana_blocktx no bp\n"); + } + } else printf("i.%d vs txn_count.%d\n",i,block->RO.txn_count); + return(0); +} + +cJSON *iguana_blockjson(struct iguana_info *coin,struct iguana_block *block,int32_t txidsflag) +{ + char str[65]; int32_t i; struct iguana_txid *tx,T; cJSON *array,*json = cJSON_CreateObject(); + jaddstr(json,"blockhash",bits256_str(str,block->RO.hash2)); + jaddnum(json,"height",block->height); + jaddnum(json,"ipbits",block->fpipbits); + jaddstr(json,"merkle_root",bits256_str(str,block->RO.merkle_root)); + jaddstr(json,"prev_block",bits256_str(str,block->RO.prev_block)); + jaddnum(json,"timestamp",block->RO.timestamp); + jaddnum(json,"nonce",block->RO.nonce); + jaddnum(json,"nBits",block->RO.bits); + jaddnum(json,"version",block->RO.version); + jaddnum(json,"numvouts",block->RO.numvouts); + jaddnum(json,"numvins",block->RO.numvins); + jaddnum(json,"recvlen",block->RO.recvlen); + jaddnum(json,"hdrsi",block->hdrsi); + jaddnum(json,"PoW",block->PoW); + jaddnum(json,"bundlei",block->bundlei); + jaddnum(json,"mainchain",block->mainchain); + jaddnum(json,"valid",block->valid); + jaddnum(json,"txn_count",block->RO.txn_count); + if ( txidsflag != 0 ) + { + array = cJSON_CreateArray(); + for (i=0; iRO.txn_count; i++) + { + if ( (tx= iguana_blocktx(coin,&T,block,i)) != 0 ) + jaddistr(array,bits256_str(str,tx->txid)); + } + jadd(json,"txids",array); + //printf("add txids[%d]\n",block->txn_count); + } + return(json); +} + +cJSON *iguana_voutjson(struct iguana_info *coin,struct iguana_msgvout *vout,char *asmstr) +{ + static bits256 zero; + char scriptstr[8192+1],coinaddr[65]; int32_t i,M,N; uint8_t rmd160[20],msigs160[16][20],addrtype; + cJSON *addrs,*json = cJSON_CreateObject(); + jaddnum(json,"value",dstr(vout->value)); + if ( asmstr[0] != 0 ) + jaddstr(json,"asm",asmstr); + if ( vout->pk_script != 0 && vout->pk_scriptlen*2+1 < sizeof(scriptstr) ) + { + if ( iguana_calcrmd160(coin,rmd160,msigs160,&M,&N,vout->pk_script,vout->pk_scriptlen,zero) > 0 ) + addrtype = coin->chain->p2shval; + else addrtype = coin->chain->pubval; + btc_convrmd160(coinaddr,addrtype,rmd160); + jaddstr(json,"address",coinaddr); + init_hexbytes_noT(scriptstr,vout->pk_script,vout->pk_scriptlen); + jaddstr(json,"payscript",scriptstr); + if ( N != 0 ) + { + jaddnum(json,"M",M); + jaddnum(json,"N",N); + addrs = cJSON_CreateArray(); + for (i=0; ichain->pubval,msigs160[i]); + jaddistr(addrs,coinaddr); + } + jadd(json,"addrs",addrs); + } + } + return(json); +} + +cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin) +{ + char scriptstr[8192+1],str[65]; cJSON *json = cJSON_CreateObject(); + jaddstr(json,"prev_hash",bits256_str(str,vin->prev_hash)); + jaddnum(json,"prev_vout",vin->prev_vout); + jaddnum(json,"sequence",vin->sequence); + if ( vin->script != 0 && vin->scriptlen*2+1 < sizeof(scriptstr) ) + { + init_hexbytes_noT(scriptstr,vin->script,vin->scriptlen); + jaddstr(json,"sigscript",scriptstr); + } + return(json); +} + +//struct iguana_txid { bits256 txid; uint32_t txidind,firstvout,firstvin,locktime,version,timestamp; uint16_t numvouts,numvins; } __attribute__((packed)); + +//struct iguana_msgvin { bits256 prev_hash; uint8_t *script; uint32_t prev_vout,scriptlen,sequence; } __attribute__((packed)); + +//struct iguana_spend { uint32_t spendtxidind; int16_t prevout; uint16_t tbd:14,external:1,diffsequence:1; } __attribute__((packed)); + +void iguana_vinset(struct iguana_info *coin,int32_t height,struct iguana_msgvin *vin,struct iguana_txid *tx,int32_t i) +{ + struct iguana_spend *s,*S; uint32_t spendind; struct iguana_bundle *bp; + struct iguana_ramchaindata *rdata; struct iguana_txid *T; bits256 *X; + memset(vin,0,sizeof(*vin)); + if ( height >= 0 && height < coin->chain->bundlesize*coin->bundlescount && (bp= coin->bundles[height / coin->chain->bundlesize]) != 0 && (rdata= bp->ramchain.H.data) != 0 ) + { + S = (void *)(long)((long)rdata + rdata->Soffset); + X = (void *)(long)((long)rdata + rdata->Xoffset); + T = (void *)(long)((long)rdata + rdata->Toffset); + spendind = (tx->firstvin + i); + s = &S[spendind]; + if ( s->diffsequence == 0 ) + vin->sequence = 0xffffffff; + vin->prev_vout = s->prevout; + iguana_ramchain_spendtxid(coin,&vin->prev_hash,T,rdata->numtxids,X,rdata->numexternaltxids,s); + } +} + +int32_t iguana_voutset(struct iguana_info *coin,uint8_t *scriptspace,char *asmstr,int32_t height,struct iguana_msgvout *vout,struct iguana_txid *tx,int32_t i) +{ + struct iguana_unspent *u,*U; uint32_t unspentind,scriptlen = 0; struct iguana_bundle *bp; + struct iguana_ramchaindata *rdata; struct iguana_pkhash *P,*p; + memset(vout,0,sizeof(*vout)); + if ( height >= 0 && height < coin->chain->bundlesize*coin->bundlescount && (bp= coin->bundles[height / coin->chain->bundlesize]) != 0 && (rdata= bp->ramchain.H.data) != 0 ) + { + U = (void *)(long)((long)rdata + rdata->Uoffset); + P = (void *)(long)((long)rdata + rdata->Poffset); + unspentind = (tx->firstvout + i); + u = &U[unspentind]; + if ( u->txidind != tx->txidind || u->vout != i || u->hdrsi != height / coin->chain->bundlesize ) + printf("iguana_voutset: txidind mismatch %d vs %d || %d vs %d || (%d vs %d)\n",u->txidind,u->txidind,u->vout,i,u->hdrsi,height / coin->chain->bundlesize); + p = &P[u->pkind]; + vout->value = u->value; + scriptlen = iguana_scriptgen(coin,scriptspace,asmstr,bp,p,u->type); + } + vout->pk_scriptlen = scriptlen; + return(scriptlen); +} + +cJSON *iguana_txjson(struct iguana_info *coin,struct iguana_txid *tx,int32_t height) +{ + struct iguana_msgvin vin; struct iguana_msgvout vout; int32_t i; char asmstr[512],str[65]; uint8_t space[8192]; + cJSON *vouts,*vins,*json; + json = cJSON_CreateObject(); + jaddstr(json,"txid",bits256_str(str,tx->txid)); + if ( height >= 0 ) + jaddnum(json,"height",height); + jaddnum(json,"version",tx->version); + jaddnum(json,"timestamp",tx->timestamp); + jaddnum(json,"locktime",tx->locktime); + vins = cJSON_CreateArray(); + vouts = cJSON_CreateArray(); + for (i=0; inumvouts; i++) + { + iguana_voutset(coin,space,asmstr,height,&vout,tx,i); + jaddi(vouts,iguana_voutjson(coin,&vout,asmstr)); + } + jadd(json,"vouts",vouts); + for (i=0; inumvins; i++) + { + iguana_vinset(coin,height,&vin,tx,i); + jaddi(vins,iguana_vinjson(coin,&vin)); + } + jadd(json,"vins",vins); + return(json); +} + +char *iguana_listsinceblock(struct supernet_info *myinfo,struct iguana_info *coin,bits256 blockhash,int32_t target) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + +char *ramchain_coinparser(struct supernet_info *myinfo,struct iguana_info *coin,char *method,cJSON *json) +{ + char *hashstr,*txidstr,*coinaddr,*txbytes,rmd160str[41],str[65]; int32_t len,height,i,n,valid = 0; + cJSON *addrs,*retjson,*retitem; uint8_t rmd160[20],addrtype; bits256 hash2,checktxid; + memset(&hash2,0,sizeof(hash2)); struct iguana_txid *tx,T; struct iguana_block *block = 0; + if ( coin == 0 && (coin= iguana_coinselect()) == 0 ) + return(clonestr("{\"error\":\"ramchain_coinparser needs coin\"}")); + if ( (coinaddr= jstr(json,"address")) != 0 ) + { + if ( btc_addr2univ(&addrtype,rmd160,coinaddr) == 0 ) + { + if ( addrtype == coin->chain->pubval || addrtype == coin->chain->p2shval ) + valid = 1; + else return(clonestr("{\"error\":\"invalid addrtype\"}")); + } else return(clonestr("{\"error\":\"cant convert address to rmd160\"}")); + } + if ( strcmp(method,"block") == 0 ) + { + height = -1; + if ( ((hashstr= jstr(json,"blockhash")) != 0 || (hashstr= jstr(json,"hash")) != 0) && strlen(hashstr) == sizeof(bits256)*2 ) + decode_hex(hash2.bytes,sizeof(hash2),hashstr); + else + { + height = juint(json,"height"); + hash2 = iguana_blockhash(coin,height); + } + retitem = cJSON_CreateObject(); + if ( (block= iguana_blockfind(coin,hash2)) != 0 ) + { + if ( (height >= 0 && block->height == height) || memcmp(hash2.bytes,block->RO.hash2.bytes,sizeof(hash2)) == 0 ) + { + char str[65],str2[65]; printf("hash2.(%s) -> %s\n",bits256_str(str,hash2),bits256_str(str2,block->RO.hash2)); + return(jprint(iguana_blockjson(coin,block,juint(json,"txids")),1)); + } + } + else return(clonestr("{\"error\":\"cant find block\"}")); + } + else if ( strcmp(method,"tx") == 0 ) + { + if ( ((txidstr= jstr(json,"txid")) != 0 || (txidstr= jstr(json,"hash")) != 0) && strlen(txidstr) == sizeof(bits256)*2 ) + { + retitem = cJSON_CreateObject(); + decode_hex(hash2.bytes,sizeof(hash2),txidstr); + if ( (tx= iguana_txidfind(coin,&height,&T,hash2)) != 0 ) + { + jadd(retitem,"tx",iguana_txjson(coin,tx,height)); + return(jprint(retitem,1)); + } + return(clonestr("{\"error\":\"cant find txid\"}")); + } + else return(clonestr("{\"error\":\"invalid txid\"}")); + } + else if ( strcmp(method,"rawtx") == 0 ) + { + if ( ((txidstr= jstr(json,"txid")) != 0 || (txidstr= jstr(json,"hash")) != 0) && strlen(txidstr) == sizeof(bits256)*2 ) + { + decode_hex(hash2.bytes,sizeof(hash2),txidstr); + if ( (tx= iguana_txidfind(coin,&height,&T,hash2)) != 0 ) + { + if ( (len= iguana_txbytes(coin,coin->blockspace,sizeof(coin->blockspace),&checktxid,tx,height,0,0)) > 0 ) + { + txbytes = mycalloc('x',1,len*2+1); + init_hexbytes_noT(txbytes,coin->blockspace,len*2+1); + retitem = cJSON_CreateObject(); + jaddstr(retitem,"txid",bits256_str(str,hash2)); + jaddnum(retitem,"height",height); + jaddstr(retitem,"rawtx",txbytes); + myfree(txbytes,len*2+1); + return(jprint(retitem,1)); + } else return(clonestr("{\"error\":\"couldnt generate txbytes\"}")); + } + return(clonestr("{\"error\":\"cant find txid\"}")); + } + else return(clonestr("{\"error\":\"invalid txid\"}")); + } + else if ( strcmp(method,"txs") == 0 ) + { + if ( ((hashstr= jstr(json,"block")) != 0 || (hashstr= jstr(json,"blockhash")) != 0) && strlen(hashstr) == sizeof(bits256)*2 ) + { + decode_hex(hash2.bytes,sizeof(hash2),hashstr); + if ( (block= iguana_blockfind(coin,hash2)) == 0 ) + return(clonestr("{\"error\":\"cant find blockhash\"}")); + } + else if ( jobj(json,"height") != 0 ) + { + height = juint(json,"height"); + hash2 = iguana_blockhash(coin,height); + if ( (block= iguana_blockfind(coin,hash2)) == 0 ) + return(clonestr("{\"error\":\"cant find block at height\"}")); + } + else if ( valid == 0 ) + return(clonestr("{\"error\":\"txs needs blockhash or height or address\"}")); + retitem = cJSON_CreateArray(); + if ( block != 0 ) + { + for (i=0; iRO.txn_count; i++) + { + if ( (tx= iguana_blocktx(coin,&T,block,i)) != 0 ) + jaddi(retitem,iguana_txjson(coin,tx,-1)); + } + } + else + { + init_hexbytes_noT(rmd160str,rmd160,20); + jaddnum(retitem,"addrtype",addrtype); + jaddstr(retitem,"rmd160",rmd160str); + jaddstr(retitem,"txlist","get list of all tx for this address"); + } + return(jprint(retitem,1)); + } + else if ( strcmp(method,"status") == 0 || strcmp(method,"getinfo") == 0 ) + { + retitem = cJSON_CreateObject(); + jaddstr(retitem,"result",coin->statusstr); + return(jprint(retitem,1)); + } + else if ( strcmp(method,"getbestblockhash") == 0 ) + { + retitem = cJSON_CreateObject(); + jaddstr(retitem,"result",bits256_str(str,coin->blocks.hwmchain.RO.hash2)); + return(jprint(retitem,1)); + } + else if ( strcmp(method,"getblockcount") == 0 ) + { + retitem = cJSON_CreateObject(); + jaddnum(retitem,"result",coin->blocks.hwmchain.height); + return(jprint(retitem,1)); + } + else if ( strcmp(method,"validatepubkey") == 0 ) + return(jprint(iguana_pubkeyjson(coin,jstr(json,"pubkey")),1)); +/* +return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","vanitygen","vanity",params[0])); +return(sglue3(0,myinfo,coin,remoteaddr,"ramchain","createmultisig","M",params[0],"pubkeys",params[1],"account",params[2])); +return(sglue3(0,myinfo,coin,remoteaddr,"ramchain","listtransactions","account",params[0],"count",params[1],"from",params[2])); +return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","getreceivedbyaddress","address",params[0],"minconfs",params[1])); +return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","listreceivedbyaddress","minconf",params[0],"includeempty",params[1])); +return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","listsinceblock","blockhash",params[0],"target",params[1])); +return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","getreceivedbyaccount","account",params[0],"minconfs",params[1])); +return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","listreceivedbyaccount","account",params[0],"includeempty",params[1]));*/ + else if ( strcmp(method,"listtransactions") == 0 ) + return(iguana_listtransactions(myinfo,coin,jstr(json,"account"),juint(json,"count"),juint(json,"from"))); + else if ( strcmp(method,"getreceivedbyaddress") == 0 ) + return(iguana_getreceivedbyaddress(myinfo,coin,jstr(json,"address"),juint(json,"minconf"))); + else if ( strcmp(method,"listreceivedbyaddress") == 0 ) + return(iguana_listreceivedbyaddress(myinfo,coin,juint(json,"minconf"),juint(json,"includeempty"))); + else if ( strcmp(method,"listsinceblock") == 0 ) + return(iguana_listsinceblock(myinfo,coin,jbits256(json,"blockhash"),juint(json,"target"))); + else if ( strcmp(method,"getreceivedbyaccount") == 0 ) + return(iguana_getreceivedbyaccount(myinfo,coin,jstr(json,"account"),juint(json,"minconf"))); + else if ( strcmp(method,"listreceivedbyaccount") == 0 ) + return(iguana_listreceivedbyaccount(myinfo,coin,jstr(json,"account"),juint(json,"includeempty"))); + /* -return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getnewaddress","account",params[0])); + -return(sglue(0,myinfo,coin,remoteaddr,"ramchain","makekeypair")); + -return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getaccountaddress","account",params[0])); + -return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","setaccount","address",params[0],"account",params[1])); + -return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getaccount","address",params[0])); + -return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getaddressesbyaccount","account",params[0])); + -return(sglue(0,myinfo,coin,remoteaddr,"ramchain","listaddressgroupings")); + -return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getbalance","account",params[0],"minconf",params[1]) + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","listaccounts","minconf",params[0]));*/ + else if ( strcmp(method,"getnewaddress") == 0 ) + return(iguana_getnewaddress(myinfo,coin,jstr(json,"account"))); + else if ( strcmp(method,"makekeypair") == 0 ) + return(iguana_makekeypair(myinfo,coin)); + else if ( strcmp(method,"getaccountaddress") == 0 ) + return(iguana_getaccountaddress(myinfo,coin,jstr(json,"account"))); + else if ( strcmp(method,"setaccount") == 0 ) + return(iguana_setaccount(myinfo,coin,jstr(json,"account"))); + else if ( strcmp(method,"getaccount") == 0 ) + return(iguana_getaccount(myinfo,coin,jstr(json,"account"))); + else if ( strcmp(method,"getaddressesbyaccount") == 0 ) + return(iguana_getaddressesbyaccount(myinfo,coin,jstr(json,"account"))); + else if ( strcmp(method,"listaddressgroupings") == 0 ) + return(iguana_listaddressgroupings(myinfo,coin)); + else if ( strcmp(method,"getbalance") == 0 ) + return(iguana_getbalance(myinfo,coin,jstr(json,"account"),juint(json,"minconf"))); + else if ( strcmp(method,"listaccounts") == 0 ) + return(iguana_listaccounts(myinfo,coin,juint(json,"minconf"))); + + /* + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","dumpprivkey","address",params[0])); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","importprivkey","wip",params[0])); + return(sglue(0,myinfo,coin,remoteaddr,"ramchain","dumpwallet")); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","importwallet","wallet",params[0])); +return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","walletpassphrase","passphrase",params[0],"timeout",params[1])); +return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","walletpassphrasechange","oldpassphrase",params[0],"newpassphrase",params[1])); + return(sglue(0,myinfo,coin,remoteaddr,"ramchain","walletlock")); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","encryptwallet","passphrase",params[0])); + return(sglue(0,myinfo,coin,remoteaddr,"ramchain","checkwallet")); + return(sglue(0,myinfo,coin,remoteaddr,"ramchain","repairwallet")); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","backupwallet","filename",params[0])); + */ + else if ( strcmp(method,"dumpprivkey") == 0 ) + return(iguana_dumpprivkey(myinfo,coin,jstr(json,"address"))); + else if ( strcmp(method,"importprivkey") == 0 ) + return(iguana_importprivkey(myinfo,coin,jstr(json,"wip"))); + else if ( strcmp(method,"dumpwallet") == 0 ) + return(iguana_dumpwallet(myinfo,coin)); + else if ( strcmp(method,"importwallet") == 0 ) + return(iguana_importwallet(myinfo,coin,jstr(json,"wallet"))); + else if ( strcmp(method,"walletpassphrase") == 0 ) + return(iguana_walletpassphrase(myinfo,coin,jstr(json,"passphrase"),juint(json,"timeout"))); + else if ( strcmp(method,"walletpassphrasechange") == 0 ) + return(iguana_walletpassphrasechange(myinfo,coin,jstr(json,"oldpassphrase"),jstr(json,"newpassphrase"))); + else if ( strcmp(method,"walletlock") == 0 ) + return(iguana_walletlock(myinfo,coin)); + else if ( strcmp(method,"encryptwallet") == 0 ) + return(iguana_encryptwallet(myinfo,coin,jstr(json,"passphrase"))); + else if ( strcmp(method,"checkwallet") == 0 ) + return(iguana_checkwallet(myinfo,coin)); + else if ( strcmp(method,"repairwallet") == 0 ) + return(iguana_repairwallet(myinfo,coin)); + else if ( strcmp(method,"backupwallet") == 0 ) + return(iguana_backupwallet(myinfo,coin,jstr(json,"filename"))); + + /* +return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","signmessage","address",params[0],"message",params[1])); +return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","verifymessage","address",params[0],"sig",params[1],"message",params[2])); +return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","listunspent","minconf",params[0],"maxconf",params[1])); + return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","lockunspent","unlock",params[0],"array",params[1])); + return(sglue(0,myinfo,coin,remoteaddr,"ramchain","listlockunspent")); +return(sglue3(0,myinfo,coin,remoteaddr,"ramchain","gettxout","txid",params[0],"vout",params[1],"mempool",params[2])); + return(sglue(0,myinfo,coin,remoteaddr,"ramchain","gettxoutsetinfo")); + */ + else if ( strcmp(method,"signmessage") == 0 ) + return(iguana_signmessage(myinfo,coin,jstr(json,"address"),jstr(json,"message"))); + else if ( strcmp(method,"verifymessage") == 0 ) + return(iguana_verifymessage(myinfo,coin,jstr(json,"address"),jstr(json,"sig"),jstr(json,"message"))); + else if ( strcmp(method,"listunspent") == 0 ) + return(iguana_listunspent(myinfo,coin,juint(json,"minconf"),juint(json,"maxconf"))); + else if ( strcmp(method,"lockunspent") == 0 ) + return(iguana_lockunspent(myinfo,coin,jstr(json,"filename"))); + else if ( strcmp(method,"listlockunspent") == 0 ) + return(iguana_listlockunspent(myinfo,coin,jstr(json,"unlock"),jobj(json,"array"))); + else if ( strcmp(method,"gettxout") == 0 ) + return(iguana_gettxout(myinfo,coin,jbits256(json,"txid"),juint(json,"vout"),juint(json,"mempool"))); + else if ( strcmp(method,"gettxoutsetinfo") == 0 ) + return(iguana_gettxoutsetinfo(myinfo,coin)); + + /* +return(sglue4(0,myinfo,coin,remoteaddr,"ramchain","sendtoaddress","address",params[0],"amount",params[1],"comment",params[2],"comment2",params[3])); +return(sglue5(0,myinfo,coin,remoteaddr,"ramchain","move","fromaccount",params[0],"toaccount",params[1],"amount",params[2],"minconf",params[3],"comment",params[4])); +return(sglue6(0,myinfo,coin,remoteaddr,"ramchain","sendfrom","fromaccount",params[0],"toaddress",params[1],"amount",params[2],"minconf",params[3],"comment",params[4],"comment2",params[5])); +return(sglue4(0,myinfo,coin,remoteaddr,"ramchain","sendmany","fromaccount",params[0],"payments",params[1],"minconf",params[2],"comment",params[3])); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","settxfee","amount",params[0])); + */ + else if ( strcmp(method,"sendtoaddress") == 0 ) + return(iguana_sendtoaddress(myinfo,coin,jstr(json,"address"),jdouble(json,"amount"),jstr(json,"comment"),jstr(json,"comment2"))); + else if ( strcmp(method,"move") == 0 ) + return(iguana_move(myinfo,coin,jstr(json,"fromaccount"),jstr(json,"toaccount"),jdouble(json,"amount"),juint(json,"minconf"),jstr(json,"comment"))); + else if ( strcmp(method,"sendfrom") == 0 ) + return(iguana_sendfrom(myinfo,coin,jstr(json,"fromaccount"),jstr(json,"toaddress"),jdouble(json,"amount"),juint(json,"minconf"),jstr(json,"comment"),jstr(json,"comment2"))); + else if ( strcmp(method,"sendmany") == 0 ) + return(iguana_sendmany(myinfo,coin,jstr(json,"fromaccount"),jobj(json,"payments"),juint(json,"minconf"),jstr(json,"comment"))); + else if ( strcmp(method,"settxfee") == 0 ) + return(iguana_settxfee(myinfo,coin,jdouble(json,"amount"))); + +/* +return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getrawtransaction","txid",params[0],"verbose",params[1])); +return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","createrawtransaction","vins",params[0],"vouts",params[1])); +return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","decoderawtransaction","rawtx",params[0])); +return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","decodescript","script",params[0])); +return(sglue3(0,myinfo,coin,remoteaddr,"ramchain","signrawtransaction","rawtx",params[0],"vins",params[1],"privkeys",params[2])); +return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","sendrawtransaction","rawtx",params[0])); +return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getrawchangeaddress","account",params[0])); +*/ + else if ( strcmp(method,"getrawtransaction") == 0 ) + return(iguana_getrawtransaction(myinfo,coin,jbits256(json,"txid"),juint(json,"verbose"))); + else if ( strcmp(method,"createrawtransaction") == 0 ) + return(iguana_createrawtransaction(myinfo,coin,jobj(json,"vins"),jobj(json,"vouts"))); + else if ( strcmp(method,"decoderawtransaction") == 0 ) + return(iguana_decoderawtransaction(myinfo,coin,jstr(json,"rawtx"))); + else if ( strcmp(method,"decodescript") == 0 ) + return(iguana_decodescript(myinfo,coin,jstr(json,"script"))); + else if ( strcmp(method,"signrawtransaction") == 0 ) + return(iguana_signrawtransaction(myinfo,coin,jstr(json,"rawtx"),jobj(json,"vins"),jobj(json,"privkeys"))); + else if ( strcmp(method,"sendrawtransaction") == 0 ) + return(iguana_sendrawtransaction(myinfo,coin,jstr(json,"rawtx"))); + else if ( strcmp(method,"getrawchangeaddress") == 0 ) + return(iguana_getrawchangeaddress(myinfo,coin,jstr(json,"account"))); + else + { + n = 0; + if ( valid == 0 ) + { + if ( (addrs= jarray(&n,json,"addrs")) == 0 ) + return(clonestr("{\"error\":\"need address or addrs\"}")); + } + for (i=0; i<=n; i++) + { + retitem = cJSON_CreateObject(); + if ( i > 0 ) + retjson = cJSON_CreateArray(); + if ( i > 0 ) + { + if ( (coinaddr= jstr(jitem(addrs,i-1),0)) == 0 ) + return(clonestr("{\"error\":\"missing address in addrs\"}")); + if ( btc_addr2univ(&addrtype,rmd160,coinaddr) < 0 ) + { + free_json(retjson); + return(clonestr("{\"error\":\"illegal address in addrs\"}")); + } + if ( addrtype != coin->chain->pubval && addrtype != coin->chain->p2shval ) + return(clonestr("{\"error\":\"invalid addrtype in addrs\"}")); + } + if ( strcmp(method,"utxo") == 0 ) + { + jaddstr(retitem,"utxo","utxo entry"); + } + else if ( strcmp(method,"unconfirmed") == 0 ) + { + jaddstr(retitem,"unconfirmed","unconfirmed entry"); + } + else if ( strcmp(method,"balance") == 0 ) + { + jaddstr(retitem,"balance","balance entry"); + } + else if ( strcmp(method,"totalreceived") == 0 ) + { + jaddstr(retitem,"totalreceived","totalreceived entry"); + } + else if ( strcmp(method,"totalsent") == 0 ) + { + jaddstr(retitem,"totalsent","totalsent entry"); + } + else if ( strcmp(method,"validateaddress") == 0 ) + { + jaddstr(retitem,"validate",coinaddr); + } + if ( n == 0 ) + return(jprint(retitem,1)); + else jaddi(retjson,retitem); + } + return(jprint(retjson,1)); + } + return(clonestr("{\"error\":\"illegal ramchain method or missing coin\"}")); +} + +char *iguana_jsoncheck(char *retstr,int32_t freeflag) +{ + cJSON *retjson; char *errstr; + if ( retstr != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (errstr= jstr(retjson,"error")) == 0 ) + { + free_json(retjson); + return(retstr); + } + free_json(retjson); + } + if ( freeflag != 0 ) + free(retstr); + } + return(0); +} + +char *ramchain_parser(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr) +{ + char *symbol,*str,*retstr; int32_t height; cJSON *argjson,*obj; struct iguana_info *coin = 0; + /*{"agent":"ramchain","method":"block","coin":"BTCD","hash":""} + {"agent":"ramchain","method":"block","coin":"BTCD","height":345600} + {"agent":"ramchain","method":"tx","coin":"BTCD","txid":""} + {"agent":"ramchain","method":"rawtx","coin":"BTCD","txid":""} + {"agent":"ramchain","method":"balance","coin":"BTCD","address":""} + {"agent":"ramchain","method":"balance","coin":"BTCD","addrs":["",...]} + {"agent":"ramchain","method":"totalreceived","coin":"BTCD","address":""} + {"agent":"ramchain","method":"totalsent","coin":"BTCD","address":""} + {"agent":"ramchain","method":"unconfirmed","coin":"BTCD","address":""} + {"agent":"ramchain","method":"utxo","coin":"BTCD","address":""} + {"agent":"ramchain","method":"utxo","coin":"BTCD","addrs":["", "",...]} + {"agent":"ramchain","method":"txs","coin":"BTCD","block":""} + {"agent":"ramchain","method":"txs","coin":"BTCD","height":12345} + {"agent":"ramchain","method":"txs","coin":"BTCD","address":""} + {"agent":"ramchain","method":"status","coin":"BTCD"}*/ + if ( (symbol= jstr(json,"coin")) != 0 && symbol[0] != 0 ) + { + if ( coin == 0 ) + coin = iguana_coinfind(symbol); + else if ( strcmp(symbol,coin->symbol) != 0 ) + return(clonestr("{\"error\":\"mismatched coin symbol\"}")); + } + if ( strcmp(method,"explore") == 0 ) + { + obj = jobj(json,"search"); + if ( coin != 0 && obj != 0 ) + { + argjson = cJSON_CreateObject(); + jaddstr(argjson,"agent","ramchain"); + jaddstr(argjson,"method","block"); + jaddnum(argjson,"txids",1); + if ( is_cJSON_Number(obj) != 0 ) + { + height = juint(obj,0); + jaddnum(argjson,"height",height); + } + else if ( (str= jstr(obj,0)) != 0 ) + jaddstr(argjson,"hash",str); + else return(clonestr("{\"error\":\"need number or string to search\"}")); + if ( (retstr= iguana_jsoncheck(ramchain_coinparser(myinfo,coin,"block",argjson),1)) != 0 ) + { + free_json(argjson); + return(retstr); + } + free_json(argjson); + argjson = cJSON_CreateObject(); + jaddstr(argjson,"agent","ramchain"); + jaddstr(argjson,"method","tx"); + jaddstr(argjson,"txid",str); + if ( (retstr= iguana_jsoncheck(ramchain_coinparser(myinfo,coin,"tx",argjson),1)) != 0 ) + { + free_json(argjson); + return(retstr); + } + free_json(argjson); + return(clonestr("{\"result\":\"explore search cant find height, blockhash, txid\"}")); + } + return(clonestr("{\"result\":\"explore no coin or search\"}")); + } + return(ramchain_coinparser(myinfo,coin,method,json)); +} diff --git a/iguana/iguana_pubkeys.c b/iguana/iguana_pubkeys.c index 85fb8937b..b33773a6b 100755 --- a/iguana/iguana_pubkeys.c +++ b/iguana/iguana_pubkeys.c @@ -1106,4 +1106,99 @@ if ( bp_key_init(&key) != 0 && bp_key_secret_set(&key,privkey,32) != 0 ) free(T); return(clonestr(hexstr)); } -*/ \ No newline at end of file +*/ +struct iguana_waddress *iguana_waddresscalc(struct iguana_info *coin,struct iguana_waddress *addr,bits256 privkey) +{ + memset(addr,0,sizeof(*addr)); + addr->privkey = privkey; + if ( btc_priv2pub(addr->pubkey,addr->privkey.bytes) == 0 && btc_priv2wip(addr->wipstr,addr->privkey.bytes,coin->chain->wipval) == 0 && btc_pub2rmd(addr->rmd160,addr->pubkey) == 0 && btc_convrmd160(addr->coinaddr,coin->chain->pubval,addr->rmd160) == 0 ) + { + addr->wiptype = coin->chain->wipval; + addr->type = coin->chain->pubval; + return(addr); + } + return(0); +} + +/*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(); + if ( iguana_waddresscalc(coin,&addr,rand256(1)) == 0 ) + { + init_hexbytes_noT(str,addr.pubkey,33); + jaddstr(retjson,"result",str); + jaddstr(retjson,"privkey",bits256_str(str,addr.privkey)); + } else jaddstr(retjson,"error","cant create address"); + return(jprint(retjson,1)); +} + +cJSON *iguana_pubkeyjson(struct iguana_info *coin,char *pubkeystr) +{ + cJSON *json = cJSON_CreateObject(); + return(json); +} + +char *iguana_signmessage(struct supernet_info *myinfo,struct iguana_info *coin,char *address,char *message) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_verifymessage(struct supernet_info *myinfo,struct iguana_info *coin,char *address,char *sig,char *message) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_getnewaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *account) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_makekeypair(struct supernet_info *myinfo,struct iguana_info *coin) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_vanitygen(struct supernet_info *myinfo,struct iguana_info *coin,char *vanity) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_createmultisig(struct supernet_info *myinfo,struct iguana_info *coin,int32_t M,cJSON *pubkeys,char *account) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + + + diff --git a/iguana/iguana_rpc.c b/iguana/iguana_rpc.c index d2d6ede4c..dd582c3ad 100755 --- a/iguana/iguana_rpc.c +++ b/iguana/iguana_rpc.c @@ -16,462 +16,128 @@ #include "iguana777.h" #include "SuperNET.h" -struct iguana_txid *iguana_blocktx(struct iguana_info *coin,struct iguana_txid *tx,struct iguana_block *block,int32_t i) +#define RPCARGS struct supernet_info *myinfo,struct iguana_info *coin,cJSON *params[],int32_t n,cJSON *json,char *remoteaddr + +char *sglue(cJSON *json,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,char *agent,char *method) { - struct iguana_bundle *bp; uint32_t txidind; - if ( i >= 0 && i < block->RO.txn_count ) + char *retstr,*rpcretstr; cJSON *retjson,*result,*error; int32_t i,j,len; + if ( json == 0 ) + json = cJSON_CreateObject(); + jaddstr(json,"agent",agent); + jaddstr(json,"method",method); + jaddstr(json,"coin",coin->symbol); + if ( (retstr= SuperNET_JSON(myinfo,json,remoteaddr)) != 0 ) { - if ( block->height >= 0 ) // + if ( (retjson= cJSON_Parse(retstr)) != 0 ) { - if ( (bp= coin->bundles[block->hdrsi]) != 0 ) + jdelete(retjson,"tag"); + //printf("RPCret.(%s) n.%d\n",jprint(retjson,0),cJSON_GetArraySize(retjson)); + result = cJSON_GetObjectItem(retjson,"result"); + error = cJSON_GetObjectItem(retjson,"error"); + if ( result != 0 && cJSON_GetArraySize(retjson) == 1 ) { - if ( (txidind= block->RO.firsttxidind) > 0 )//bp->firsttxidinds[block->bundlei]) > 0 ) + if ( (error == 0 || (error->type&0xff) == cJSON_NULL) && (result->type&0xff) != cJSON_NULL ) { - if ( iguana_bundletx(coin,bp,block->bundlei,tx,txidind+i) == tx ) - return(tx); - printf("error getting txidind.%d + i.%d from hdrsi.%d\n",txidind,i,block->hdrsi); - return(0); - } else printf("iguana_blocktx null txidind\n"); - } else printf("iguana_blocktx no bp\n"); - } - } else printf("i.%d vs txn_count.%d\n",i,block->RO.txn_count); - return(0); -} - -cJSON *iguana_blockjson(struct iguana_info *coin,struct iguana_block *block,int32_t txidsflag) -{ - char str[65]; int32_t i; struct iguana_txid *tx,T; cJSON *array,*json = cJSON_CreateObject(); - jaddstr(json,"blockhash",bits256_str(str,block->RO.hash2)); - jaddnum(json,"height",block->height); - jaddnum(json,"ipbits",block->fpipbits); - jaddstr(json,"merkle_root",bits256_str(str,block->RO.merkle_root)); - jaddstr(json,"prev_block",bits256_str(str,block->RO.prev_block)); - jaddnum(json,"timestamp",block->RO.timestamp); - jaddnum(json,"nonce",block->RO.nonce); - jaddnum(json,"nBits",block->RO.bits); - jaddnum(json,"version",block->RO.version); - jaddnum(json,"numvouts",block->RO.numvouts); - jaddnum(json,"numvins",block->RO.numvins); - jaddnum(json,"recvlen",block->RO.recvlen); - jaddnum(json,"hdrsi",block->hdrsi); - jaddnum(json,"PoW",block->PoW); - jaddnum(json,"bundlei",block->bundlei); - jaddnum(json,"mainchain",block->mainchain); - jaddnum(json,"valid",block->valid); - jaddnum(json,"txn_count",block->RO.txn_count); - if ( txidsflag != 0 ) - { - array = cJSON_CreateArray(); - for (i=0; iRO.txn_count; i++) - { - if ( (tx= iguana_blocktx(coin,&T,block,i)) != 0 ) - jaddistr(array,bits256_str(str,tx->txid)); + rpcretstr = cJSON_Print(result); + len = (int32_t)strlen(rpcretstr); + if ( rpcretstr[0] == '"' && rpcretstr[len-1] == '"' ) + { + for (i=1,j=0; itype&0xff) != cJSON_NULL || (result->type&0xff) != cJSON_NULL ) + printf("<<<<<<<<<<< bitcoind_RPC: post_process_bitcoind_RPC error.%s\n",retstr); + } + free_json(retjson); } - jadd(json,"txids",array); - //printf("add txids[%d]\n",block->txn_count); } - return(json); + free_json(json); + return(retstr); } -cJSON *iguana_voutjson(struct iguana_info *coin,struct iguana_msgvout *vout,char *asmstr) +char *sglue1(cJSON *json,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,char *agent,char *method,char *field,cJSON *obj) { - static bits256 zero; - char scriptstr[8192+1],coinaddr[65]; int32_t i,M,N; uint8_t rmd160[20],msigs160[16][20],addrtype; - cJSON *addrs,*json = cJSON_CreateObject(); - jaddnum(json,"value",dstr(vout->value)); - if ( asmstr[0] != 0 ) - jaddstr(json,"asm",asmstr); - if ( vout->pk_script != 0 && vout->pk_scriptlen*2+1 < sizeof(scriptstr) ) - { - if ( iguana_calcrmd160(coin,rmd160,msigs160,&M,&N,vout->pk_script,vout->pk_scriptlen,zero) > 0 ) - addrtype = coin->chain->p2shval; - else addrtype = coin->chain->pubval; - btc_convrmd160(coinaddr,addrtype,rmd160); - jaddstr(json,"address",coinaddr); - init_hexbytes_noT(scriptstr,vout->pk_script,vout->pk_scriptlen); - jaddstr(json,"payscript",scriptstr); - if ( N != 0 ) - { - jaddnum(json,"M",M); - jaddnum(json,"N",N); - addrs = cJSON_CreateArray(); - for (i=0; ichain->pubval,msigs160[i]); - jaddistr(addrs,coinaddr); - } - jadd(json,"addrs",addrs); - } - } - return(json); + if ( json == 0 ) + json = cJSON_CreateObject(); + if ( obj != 0 ) + jadd(json,field,obj); + return(sglue(json,myinfo,coin,remoteaddr,agent,method)); } -cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin) +char *sglueN(cJSON *json,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,char *agent,char *method,char *field,double num) { - char scriptstr[8192+1],str[65]; cJSON *json = cJSON_CreateObject(); - jaddstr(json,"prev_hash",bits256_str(str,vin->prev_hash)); - jaddnum(json,"prev_vout",vin->prev_vout); - jaddnum(json,"sequence",vin->sequence); - if ( vin->script != 0 && vin->scriptlen*2+1 < sizeof(scriptstr) ) - { - init_hexbytes_noT(scriptstr,vin->script,vin->scriptlen); - jaddstr(json,"sigscript",scriptstr); - } - return(json); + if ( json == 0 ) + json = cJSON_CreateObject(); + jaddnum(json,field,num); + return(sglue(json,myinfo,coin,remoteaddr,agent,method)); } -//struct iguana_txid { bits256 txid; uint32_t txidind,firstvout,firstvin,locktime,version,timestamp; uint16_t numvouts,numvins; } __attribute__((packed)); - -//struct iguana_msgvin { bits256 prev_hash; uint8_t *script; uint32_t prev_vout,scriptlen,sequence; } __attribute__((packed)); - -//struct iguana_spend { uint32_t spendtxidind; int16_t prevout; uint16_t tbd:14,external:1,diffsequence:1; } __attribute__((packed)); - -void iguana_vinset(struct iguana_info *coin,int32_t height,struct iguana_msgvin *vin,struct iguana_txid *tx,int32_t i) +char *sglue2(cJSON *json,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,char *agent,char *method,char *field0,cJSON *obj0,char *field1,cJSON *obj1) { - struct iguana_spend *s,*S; uint32_t spendind; struct iguana_bundle *bp; - struct iguana_ramchaindata *rdata; struct iguana_txid *T; bits256 *X; - memset(vin,0,sizeof(*vin)); - if ( height >= 0 && height < coin->chain->bundlesize*coin->bundlescount && (bp= coin->bundles[height / coin->chain->bundlesize]) != 0 && (rdata= bp->ramchain.H.data) != 0 ) - { - S = (void *)(long)((long)rdata + rdata->Soffset); - X = (void *)(long)((long)rdata + rdata->Xoffset); - T = (void *)(long)((long)rdata + rdata->Toffset); - spendind = (tx->firstvin + i); - s = &S[spendind]; - if ( s->diffsequence == 0 ) - vin->sequence = 0xffffffff; - vin->prev_vout = s->prevout; - iguana_ramchain_spendtxid(coin,&vin->prev_hash,T,rdata->numtxids,X,rdata->numexternaltxids,s); - } + if ( json == 0 ) + json = cJSON_CreateObject(); + if ( obj1 != 0 ) + jadd(json,field1,obj1); + return(sglue1(json,myinfo,coin,remoteaddr,agent,method,field0,obj0)); } -int32_t iguana_voutset(struct iguana_info *coin,uint8_t *scriptspace,char *asmstr,int32_t height,struct iguana_msgvout *vout,struct iguana_txid *tx,int32_t i) +char *sglue3(cJSON *json,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,char *agent,char *method,char *field0,cJSON *obj0,char *field1,cJSON *obj1,char *field2,cJSON *obj2) { - struct iguana_unspent *u,*U; uint32_t unspentind,scriptlen = 0; struct iguana_bundle *bp; - struct iguana_ramchaindata *rdata; struct iguana_pkhash *P,*p; - memset(vout,0,sizeof(*vout)); - if ( height >= 0 && height < coin->chain->bundlesize*coin->bundlescount && (bp= coin->bundles[height / coin->chain->bundlesize]) != 0 && (rdata= bp->ramchain.H.data) != 0 ) - { - U = (void *)(long)((long)rdata + rdata->Uoffset); - P = (void *)(long)((long)rdata + rdata->Poffset); - unspentind = (tx->firstvout + i); - u = &U[unspentind]; - if ( u->txidind != tx->txidind || u->vout != i || u->hdrsi != height / coin->chain->bundlesize ) - printf("iguana_voutset: txidind mismatch %d vs %d || %d vs %d || (%d vs %d)\n",u->txidind,u->txidind,u->vout,i,u->hdrsi,height / coin->chain->bundlesize); - p = &P[u->pkind]; - vout->value = u->value; - scriptlen = iguana_scriptgen(coin,scriptspace,asmstr,bp,p,u->type); - } - vout->pk_scriptlen = scriptlen; - return(scriptlen); -} - -cJSON *iguana_txjson(struct iguana_info *coin,struct iguana_txid *tx,int32_t height) -{ - struct iguana_msgvin vin; struct iguana_msgvout vout; int32_t i; char asmstr[512],str[65]; uint8_t space[8192]; - cJSON *vouts,*vins,*json; - json = cJSON_CreateObject(); - jaddstr(json,"txid",bits256_str(str,tx->txid)); - if ( height >= 0 ) - jaddnum(json,"height",height); - jaddnum(json,"version",tx->version); - jaddnum(json,"timestamp",tx->timestamp); - jaddnum(json,"locktime",tx->locktime); - vins = cJSON_CreateArray(); - vouts = cJSON_CreateArray(); - for (i=0; inumvouts; i++) - { - iguana_voutset(coin,space,asmstr,height,&vout,tx,i); - jaddi(vouts,iguana_voutjson(coin,&vout,asmstr)); - } - jadd(json,"vouts",vouts); - for (i=0; inumvins; i++) - { - iguana_vinset(coin,height,&vin,tx,i); - jaddi(vins,iguana_vinjson(coin,&vin)); - } - jadd(json,"vins",vins); - return(json); + if ( json == 0 ) + json = cJSON_CreateObject(); + if ( obj2 != 0 ) + jadd(json,field2,obj2); + return(sglue2(json,myinfo,coin,remoteaddr,agent,method,field0,obj0,field1,obj1)); } -char *ramchain_coinparser(struct iguana_info *coin,char *method,cJSON *json) +char *sglue4(cJSON *json,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,char *agent,char *method,char *field0,cJSON *obj0,char *field1,cJSON *obj1,char *field2,cJSON *obj2,char *field3,cJSON *obj3) { - char *hashstr,*txidstr,*coinaddr,*txbytes,rmd160str[41],str[65]; int32_t len,height,i,n,valid = 0; - cJSON *addrs,*retjson,*retitem; uint8_t rmd160[20],addrtype; bits256 hash2,checktxid; - memset(&hash2,0,sizeof(hash2)); struct iguana_txid *tx,T; struct iguana_block *block = 0; - if ( coin == 0 && (coin= iguana_coinselect()) == 0 ) - return(clonestr("{\"error\":\"ramchain_coinparser needs coin\"}")); - if ( (coinaddr= jstr(json,"address")) != 0 ) - { - if ( btc_addr2univ(&addrtype,rmd160,coinaddr) == 0 ) - { - if ( addrtype == coin->chain->pubval || addrtype == coin->chain->p2shval ) - valid = 1; - else return(clonestr("{\"error\":\"invalid addrtype\"}")); - } else return(clonestr("{\"error\":\"cant convert address to rmd160\"}")); - } - if ( strcmp(method,"block") == 0 ) - { - height = -1; - if ( ((hashstr= jstr(json,"blockhash")) != 0 || (hashstr= jstr(json,"hash")) != 0) && strlen(hashstr) == sizeof(bits256)*2 ) - decode_hex(hash2.bytes,sizeof(hash2),hashstr); - else - { - height = juint(json,"height"); - hash2 = iguana_blockhash(coin,height); - } - retitem = cJSON_CreateObject(); - if ( (block= iguana_blockfind(coin,hash2)) != 0 ) - { - if ( (height >= 0 && block->height == height) || memcmp(hash2.bytes,block->RO.hash2.bytes,sizeof(hash2)) == 0 ) - { - char str[65],str2[65]; printf("hash2.(%s) -> %s\n",bits256_str(str,hash2),bits256_str(str2,block->RO.hash2)); - return(jprint(iguana_blockjson(coin,block,juint(json,"txids")),1)); - } - } - else return(clonestr("{\"error\":\"cant find block\"}")); - } - else if ( strcmp(method,"tx") == 0 ) - { - if ( ((txidstr= jstr(json,"txid")) != 0 || (txidstr= jstr(json,"hash")) != 0) && strlen(txidstr) == sizeof(bits256)*2 ) - { - retitem = cJSON_CreateObject(); - decode_hex(hash2.bytes,sizeof(hash2),txidstr); - if ( (tx= iguana_txidfind(coin,&height,&T,hash2)) != 0 ) - { - jadd(retitem,"tx",iguana_txjson(coin,tx,height)); - return(jprint(retitem,1)); - } - return(clonestr("{\"error\":\"cant find txid\"}")); - } - else return(clonestr("{\"error\":\"invalid txid\"}")); - } - else if ( strcmp(method,"rawtx") == 0 ) - { - if ( ((txidstr= jstr(json,"txid")) != 0 || (txidstr= jstr(json,"hash")) != 0) && strlen(txidstr) == sizeof(bits256)*2 ) - { - decode_hex(hash2.bytes,sizeof(hash2),txidstr); - if ( (tx= iguana_txidfind(coin,&height,&T,hash2)) != 0 ) - { - if ( (len= iguana_txbytes(coin,coin->blockspace,sizeof(coin->blockspace),&checktxid,tx,height,0,0)) > 0 ) - { - txbytes = mycalloc('x',1,len*2+1); - init_hexbytes_noT(txbytes,coin->blockspace,len*2+1); - retitem = cJSON_CreateObject(); - jaddstr(retitem,"txid",bits256_str(str,hash2)); - jaddnum(retitem,"height",height); - jaddstr(retitem,"rawtx",txbytes); - myfree(txbytes,len*2+1); - return(jprint(retitem,1)); - } else return(clonestr("{\"error\":\"couldnt generate txbytes\"}")); - } - return(clonestr("{\"error\":\"cant find txid\"}")); - } - else return(clonestr("{\"error\":\"invalid txid\"}")); - } - else if ( strcmp(method,"txs") == 0 ) - { - if ( ((hashstr= jstr(json,"block")) != 0 || (hashstr= jstr(json,"blockhash")) != 0) && strlen(hashstr) == sizeof(bits256)*2 ) - { - decode_hex(hash2.bytes,sizeof(hash2),hashstr); - if ( (block= iguana_blockfind(coin,hash2)) == 0 ) - return(clonestr("{\"error\":\"cant find blockhash\"}")); - } - else if ( jobj(json,"height") != 0 ) - { - height = juint(json,"height"); - hash2 = iguana_blockhash(coin,height); - if ( (block= iguana_blockfind(coin,hash2)) == 0 ) - return(clonestr("{\"error\":\"cant find block at height\"}")); - } - else if ( valid == 0 ) - return(clonestr("{\"error\":\"txs needs blockhash or height or address\"}")); - retitem = cJSON_CreateArray(); - if ( block != 0 ) - { - for (i=0; iRO.txn_count; i++) - { - if ( (tx= iguana_blocktx(coin,&T,block,i)) != 0 ) - jaddi(retitem,iguana_txjson(coin,tx,-1)); - } - } - else - { - init_hexbytes_noT(rmd160str,rmd160,20); - jaddnum(retitem,"addrtype",addrtype); - jaddstr(retitem,"rmd160",rmd160str); - jaddstr(retitem,"txlist","get list of all tx for this address"); - } - return(jprint(retitem,1)); - } - else if ( strcmp(method,"status") == 0 ) - { - retitem = cJSON_CreateObject(); - jaddstr(retitem,"status","coin status"); - return(jprint(retitem,1)); - } - else - { - n = 0; - if ( valid == 0 ) - { - if ( (addrs= jarray(&n,json,"addrs")) == 0 ) - return(clonestr("{\"error\":\"need address or addrs\"}")); - } - for (i=0; i<=n; i++) - { - retitem = cJSON_CreateObject(); - if ( i > 0 ) - retjson = cJSON_CreateArray(); - if ( i > 0 ) - { - if ( (coinaddr= jstr(jitem(addrs,i-1),0)) == 0 ) - return(clonestr("{\"error\":\"missing address in addrs\"}")); - if ( btc_addr2univ(&addrtype,rmd160,coinaddr) < 0 ) - { - free_json(retjson); - return(clonestr("{\"error\":\"illegal address in addrs\"}")); - } - if ( addrtype != coin->chain->pubval && addrtype != coin->chain->p2shval ) - return(clonestr("{\"error\":\"invalid addrtype in addrs\"}")); - } - if ( strcmp(method,"utxo") == 0 ) - { - jaddstr(retitem,"utxo","utxo entry"); - } - else if ( strcmp(method,"unconfirmed") == 0 ) - { - jaddstr(retitem,"unconfirmed","unconfirmed entry"); - } - else if ( strcmp(method,"balance") == 0 ) - { - jaddstr(retitem,"balance","balance entry"); - } - else if ( strcmp(method,"totalreceived") == 0 ) - { - jaddstr(retitem,"totalreceived","totalreceived entry"); - } - else if ( strcmp(method,"totalsent") == 0 ) - { - jaddstr(retitem,"totalsent","totalsent entry"); - } - else if ( strcmp(method,"validate") == 0 ) - { - jaddstr(retitem,"validate",coinaddr); - } - if ( n == 0 ) - return(jprint(retitem,1)); - else jaddi(retjson,retitem); - } - return(jprint(retjson,1)); - } - return(clonestr("{\"error\":\"illegal ramchain method or missing coin\"}")); + if ( json == 0 ) + json = cJSON_CreateObject(); + if ( obj3 != 0 ) + jadd(json,field3,obj3); + return(sglue3(json,myinfo,coin,remoteaddr,agent,method,field0,obj0,field1,obj1,field2,obj2)); } -char *iguana_jsoncheck(char *retstr,int32_t freeflag) +char *sglue5(cJSON *json,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,char *agent,char *method,char *field0,cJSON *obj0,char *field1,cJSON *obj1,char *field2,cJSON *obj2,char *field3,cJSON *obj3,char *field4,cJSON *obj4) { - cJSON *retjson; char *errstr; - if ( retstr != 0 ) - { - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( (errstr= jstr(retjson,"error")) == 0 ) - { - free_json(retjson); - return(retstr); - } - free_json(retjson); - } - if ( freeflag != 0 ) - free(retstr); - } - return(0); -} - -char *ramchain_parser(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr) -{ - char *symbol,*str,*retstr; int32_t height; cJSON *argjson,*obj; struct iguana_info *coin = 0; - /*{"agent":"ramchain","method":"block","coin":"BTCD","hash":""} - {"agent":"ramchain","method":"block","coin":"BTCD","height":345600} - {"agent":"ramchain","method":"tx","coin":"BTCD","txid":""} - {"agent":"ramchain","method":"rawtx","coin":"BTCD","txid":""} - {"agent":"ramchain","method":"balance","coin":"BTCD","address":""} - {"agent":"ramchain","method":"balance","coin":"BTCD","addrs":["",...]} - {"agent":"ramchain","method":"totalreceived","coin":"BTCD","address":""} - {"agent":"ramchain","method":"totalsent","coin":"BTCD","address":""} - {"agent":"ramchain","method":"unconfirmed","coin":"BTCD","address":""} - {"agent":"ramchain","method":"utxo","coin":"BTCD","address":""} - {"agent":"ramchain","method":"utxo","coin":"BTCD","addrs":["", "",...]} - {"agent":"ramchain","method":"txs","coin":"BTCD","block":""} - {"agent":"ramchain","method":"txs","coin":"BTCD","height":12345} - {"agent":"ramchain","method":"txs","coin":"BTCD","address":""} - {"agent":"ramchain","method":"status","coin":"BTCD"}*/ - if ( (symbol= jstr(json,"coin")) != 0 && symbol[0] != 0 ) - { - if ( coin == 0 ) - coin = iguana_coinfind(symbol); - else if ( strcmp(symbol,coin->symbol) != 0 ) - return(clonestr("{\"error\":\"mismatched coin symbol\"}")); - } - if ( strcmp(method,"explore") == 0 ) - { - obj = jobj(json,"search"); - if ( coin != 0 && obj != 0 ) - { - argjson = cJSON_CreateObject(); - jaddstr(argjson,"agent","ramchain"); - jaddstr(argjson,"method","block"); - jaddnum(argjson,"txids",1); - if ( is_cJSON_Number(obj) != 0 ) - { - height = juint(obj,0); - jaddnum(argjson,"height",height); - } - else if ( (str= jstr(obj,0)) != 0 ) - jaddstr(argjson,"hash",str); - else return(clonestr("{\"error\":\"need number or string to search\"}")); - if ( (retstr= iguana_jsoncheck(ramchain_coinparser(coin,"block",argjson),1)) != 0 ) - { - free_json(argjson); - return(retstr); - } - free_json(argjson); - argjson = cJSON_CreateObject(); - jaddstr(argjson,"agent","ramchain"); - jaddstr(argjson,"method","tx"); - jaddstr(argjson,"txid",str); - if ( (retstr= iguana_jsoncheck(ramchain_coinparser(coin,"tx",argjson),1)) != 0 ) - { - free_json(argjson); - return(retstr); - } - free_json(argjson); - return(clonestr("{\"result\":\"explore search cant find height, blockhash, txid\"}")); - } - return(clonestr("{\"result\":\"explore no coin or search\"}")); - } - return(ramchain_coinparser(coin,method,json)); + if ( json == 0 ) + json = cJSON_CreateObject(); + if ( obj4 != 0 ) + jadd(json,field4,obj4); + return(sglue4(json,myinfo,coin,remoteaddr,agent,method,field0,obj0,field1,obj1,field2,obj2,field3,obj3)); } +char *sglue6(cJSON *json,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,char *agent,char *method,char *field0,cJSON *obj0,char *field1,cJSON *obj1,char *field2,cJSON *obj2,char *field3,cJSON *obj3,char *field4,cJSON *obj4,char *field5,cJSON *obj5) +{ + if ( json == 0 ) + json = cJSON_CreateObject(); + if ( obj5 != 0 ) + jadd(json,field5,obj5); + return(sglue5(json,myinfo,coin,remoteaddr,agent,method,field0,obj0,field1,obj1,field2,obj2,field3,obj3,field4,obj4)); +} -#define RPCARGS struct supernet_info *myinfo,struct iguana_info *coin,cJSON *params[],int32_t n,cJSON *json,char *remoteaddr - -// MAP bitcoin RPC to SuperNET JSONstr -// MAP REST to SuperNET JSONstr // misc static char *help(RPCARGS) { - return(clonestr("{\"result\":\"return help string here\n")); + return(sglue(0,myinfo,coin,remoteaddr,"SuperNET","help")); } static char *stop(RPCARGS) { - return(iguana_coinjson(coin,"pausecoin",params[0])); + return(sglue(0,myinfo,coin,remoteaddr,"iguana","pausecoin")); } static char *sendalert(RPCARGS) { - return(0); + return(sglue1(0,myinfo,coin,remoteaddr,"iguana","sendalert","message",params[0])); } static char *SuperNET(RPCARGS) @@ -481,464 +147,324 @@ static char *SuperNET(RPCARGS) static char *getrawmempool(RPCARGS) { - return(0); + return(sglue(0,myinfo,coin,remoteaddr,"iguana","getrawmempool")); } // peers static char *getconnectioncount(RPCARGS) { - int32_t i,num = 0; char buf[128]; - for (i=0; ipeers.active)/sizeof(*coin->peers.active); i++) - if ( coin->peers.active[i].usock >= 0 ) - num++; - sprintf(buf,"{\"result\":\"%d\"}",num); - return(clonestr(buf)); + return(sglue(0,myinfo,coin,remoteaddr,"iguana","getconnectioncount")); } static char *getpeerinfo(RPCARGS) { - cJSON *retjson; char buf[128]; - if ( (retjson= iguana_peersjson(coin,0)) != 0 ) - return(jprint(retjson,1)); - sprintf(buf,"{\"result\":\"%d\"}",coin->blocks.hwmchain.height + 1); - return(clonestr("{\"error\":\"no peers\"}")); + return(sglue(0,myinfo,coin,remoteaddr,"iguana","peers")); } static char *addnode(RPCARGS) { - // addnode version 0.8 Attempts add or remove from the addnode list or try a connection to once. N - return(0); -} - -// address and pubkeys -struct iguana_waddress *iguana_waddresscalc(struct iguana_info *coin,struct iguana_waddress *addr,bits256 privkey) -{ - memset(addr,0,sizeof(*addr)); - addr->privkey = privkey; - if ( btc_priv2pub(addr->pubkey,addr->privkey.bytes) == 0 && btc_priv2wip(addr->wipstr,addr->privkey.bytes,coin->chain->wipval) == 0 && btc_pub2rmd(addr->rmd160,addr->pubkey) == 0 && btc_convrmd160(addr->coinaddr,coin->chain->pubval,addr->rmd160) == 0 ) + char *mode,*cmd = 0; + if ( (mode= jstr(params[1],0)) != 0 ) { - addr->wiptype = coin->chain->wipval; - addr->type = coin->chain->pubval; - return(addr); + if ( strcmp(mode,"add") == 0 ) + cmd = "addnode"; + else if ( strcmp(mode,"remove") == 0 ) + cmd = "removenode"; + else if ( strcmp(mode,"onetry") == 0 ) + cmd = "onetry"; + if ( cmd != 0 ) + return(sglue1(0,myinfo,coin,remoteaddr,"iguana",cmd,"ipaddr",params[0])); } - return(0); -} - -int32_t iguana_addressvalidate(struct iguana_info *coin,char *coinaddr) -{ - // verify checksum bytes - return(0); -} - -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); + // addnode version 0.8 Attempts add or remove from the addnode list or try a connection to once. N + return(clonestr("{\"error\":\"invalid addnode parameter\"}")); } +// address and pubkeys static char *validateaddress(RPCARGS) { - char *coinaddr; cJSON *retjson; - retjson = cJSON_CreateObject(); - if ( params[0] != 0 && (coinaddr= jstr(params[0],0)) != 0 ) - return(validateretstr(coin,coinaddr)); - return(clonestr("{\"error\":\"need coin address\"}")); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","validateaddress","address",params[0])); } 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\"}")); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","validatepubkey","pubkey",params[0])); } static char *createmultisig(RPCARGS) { - return(0); + return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","createmultisig","M",params[0],"pubkeys",params[1])); +} + +static char *addmultisigaddress(RPCARGS) +{ + return(sglue3(0,myinfo,coin,remoteaddr,"ramchain","createmultisig","M",params[0],"pubkeys",params[1],"account",params[2])); } // blockchain static char *getinfo(RPCARGS) { - cJSON *retjson = cJSON_CreateObject(); - jaddstr(retjson,"result",coin->statusstr); - return(jprint(retjson,1)); + return(sglue(0,myinfo,coin,remoteaddr,"ramchain","status")); } static char *getbestblockhash(RPCARGS) { - char buf[512],str[65]; - sprintf(buf,"{\"result\":\"%s\"}",bits256_str(str,coin->blocks.hwmchain.RO.hash2)); - return(clonestr(buf)); + return(sglue(0,myinfo,coin,remoteaddr,"ramchain","getbestblockhash")); } static char *getblockcount(RPCARGS) { - char buf[512]; - sprintf(buf,"{\"result\":\"%d\"}",coin->blocks.hwmchain.height + 1); - return(clonestr(buf)); + return(sglue(0,myinfo,coin,remoteaddr,"ramchain","getblockcount")); } static char *getblock(RPCARGS) { - return(0); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getblock","blockhash",params[0])); } static char *getblockhash(RPCARGS) { - return(0); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getblockhash","height",params[0])); } static char *gettransaction(RPCARGS) { - return(0); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","tx","txid",params[0])); } static char *listtransactions(RPCARGS) { - return(0); + return(sglue3(0,myinfo,coin,remoteaddr,"ramchain","listtransactions","account",params[0],"count",params[1],"from",params[2])); } static char *getreceivedbyaddress(RPCARGS) { - return(0); + return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","getreceivedbyaddress","address",params[0],"minconfs",params[1])); } static char *listreceivedbyaddress(RPCARGS) { - return(0); + return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","listreceivedbyaddress","minconf",params[0],"includeempty",params[1])); } static char *listsinceblock(RPCARGS) { - return(0); + return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","listsinceblock","blockhash",params[0],"target",params[1])); } // waccount and waddress funcs static char *getreceivedbyaccount(RPCARGS) { - return(0); + return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","getreceivedbyaccount","account",params[0],"minconfs",params[1])); } static char *listreceivedbyaccount(RPCARGS) { - return(0); + return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","listreceivedbyaccount","account",params[0],"includeempty",params[1])); } -static char *addmultisigaddress(RPCARGS) +static char *getnewaddress(RPCARGS) { - return(0); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getnewaddress","account",params[0])); } -static char *getnewaddress(RPCARGS) +static char *vanitygen(RPCARGS) { - struct iguana_waddress addr; char str[67],*account; cJSON *retjson = cJSON_CreateObject(); - if ( iguana_waddresscalc(coin,&addr,rand256(1)) == 0 ) - { - jaddstr(retjson,"result",addr.coinaddr); - init_hexbytes_noT(str,addr.pubkey,33); - jaddstr(retjson,"pubkey",str); - jaddstr(retjson,"privkey",bits256_str(str,addr.privkey)); - jaddstr(retjson,"wip",addr.wipstr); - init_hexbytes_noT(str,addr.rmd160,20); - jaddstr(retjson,"rmd160",str); - if ( params[0] != 0 && (account= jstr(params[0],0)) != 0 ) - { - if ( iguana_waccountadd(coin,account,&addr) < 0 ) - jaddstr(retjson,"account","error adding to account"); - else jaddstr(retjson,"account",account); - } - } else jaddstr(retjson,"error","cant create address"); - return(jprint(retjson,1)); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","vanitygen","vanity",params[0])); } static char *makekeypair(RPCARGS) { - struct iguana_waddress addr; char str[67]; cJSON *retjson = cJSON_CreateObject(); - if ( iguana_waddresscalc(coin,&addr,rand256(1)) == 0 ) - { - init_hexbytes_noT(str,addr.pubkey,33); - jaddstr(retjson,"result",str); - jaddstr(retjson,"privkey",bits256_str(str,addr.privkey)); - } else jaddstr(retjson,"error","cant create address"); - return(jprint(retjson,1)); + return(sglue(0,myinfo,coin,remoteaddr,"ramchain","makekeypair")); } static char *getaccountaddress(RPCARGS) { - struct iguana_waccount *wacct; struct iguana_waddress *waddr=0,addr; char str[67]; char *account; cJSON *retjson; - if ( params[0] != 0 && (account= jstr(params[0],0)) != 0 ) - { - if ( (wacct= iguana_waccountfind(coin,account)) == 0 ) - { - if ( (waddr= iguana_waddresscalc(coin,&addr,rand256(1))) == 0 ) - return(clonestr("{\"error\":\"cant generate address\"}")); - iguana_waccountswitch(coin,account,0,-1,addr.coinaddr); - } - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result",waddr->coinaddr); - init_hexbytes_noT(str,addr.pubkey,33); - jaddstr(retjson,"pubkey",str); - jaddstr(retjson,"privkey",bits256_str(str,waddr->privkey)); - jaddstr(retjson,"wip",waddr->wipstr); - init_hexbytes_noT(str,waddr->rmd160,20); - jaddstr(retjson,"rmd160",str); - jaddstr(retjson,"account",account); - return(jprint(retjson,1)); - } - return(clonestr("{\"error\":\"no account specified\"}")); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getaccountaddress","account",params[0])); } static char *setaccount(RPCARGS) { - struct iguana_waccount *wacct; struct iguana_waddress *waddr=0,addr; int32_t ind=-1; char *account,*coinaddr; - if ( params[0] != 0 && (coinaddr= jstr(params[0],0)) != 0 && params[1] != 0 && (account= jstr(params[1],0)) != 0 ) - { - if ( iguana_addressvalidate(coin,coinaddr) < 0 ) - return(clonestr("{\"error\":\"invalid coin address\"}")); - if ( (wacct= iguana_waddressfind(coin,&ind,coinaddr)) == 0 ) - { - if ( (waddr= iguana_waddresscalc(coin,&addr,rand256(1))) == 0 ) - return(clonestr("{\"error\":\"cant generate address\"}")); - } - iguana_waccountswitch(coin,account,wacct,ind,coinaddr); - return(clonestr("{\"result\":\"account set\"}")); - } - return(clonestr("{\"error\":\"need address and account\"}")); + return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","setaccount","address",params[0],"account",params[1])); } static char *getaccount(RPCARGS) { - struct iguana_waccount *wacct; char *coinaddr; cJSON *retjson; int32_t ind; - if ( params[0] != 0 && (coinaddr= jstr(params[0],0)) != 0 ) - { - if ( iguana_addressvalidate(coin,coinaddr) < 0 ) - return(clonestr("{\"error\":\"invalid coin address\"}")); - if ( (wacct= iguana_waddressfind(coin,&ind,coinaddr)) == 0 ) - return(clonestr("{\"result\":\"no account for address\"}")); - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result",wacct->account); - return(jprint(retjson,1)); - } - return(clonestr("{\"error\":\"need address\"}")); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getaccount","address",params[0])); } static char *getaddressesbyaccount(RPCARGS) { - struct iguana_waccount *subset; struct iguana_waddress *waddr,*tmp; char *account; cJSON *retjson,*array; - retjson = cJSON_CreateObject(); - array = cJSON_CreateArray(); - if ( params[0] != 0 && (account= jstr(params[0],0)) != 0 ) - { - if ( (subset= iguana_waccountfind(coin,account)) != 0 ) - { - HASH_ITER(hh,subset->waddrs,waddr,tmp) - { - jaddistr(array,waddr->coinaddr); - } - } else jaddstr(retjson,"result","cant find account"); - } else jaddstr(retjson,"error","no account specified"); - jadd(retjson,"addresses",array); - return(jprint(retjson,1)); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getaddressesbyaccount","account",params[0])); } static char *listaddressgroupings(RPCARGS) { - return(0); + return(sglue(0,myinfo,coin,remoteaddr,"ramchain","listaddressgroupings")); } static char *getbalance(RPCARGS) { - return(0); + return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","getbalance","account",params[0],"minconf",params[1])); } // wallet static char *listaccounts(RPCARGS) { - return(0); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","listaccounts","minconf",params[0])); } static char *dumpprivkey(RPCARGS) { - return(0); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","dumpprivkey","address",params[0])); } static char *importprivkey(RPCARGS) { - return(0); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","importprivkey","wip",params[0])); } static char *dumpwallet(RPCARGS) { - return(0); + return(sglue(0,myinfo,coin,remoteaddr,"ramchain","dumpwallet")); } static char *importwallet(RPCARGS) { - return(0); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","importwallet","wallet",params[0])); } static char *walletpassphrase(RPCARGS) { - return(0); + return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","walletpassphrase","passphrase",params[0],"timeout",params[1])); } static char *walletpassphrasechange(RPCARGS) { - return(0); + return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","walletpassphrasechange","oldpassphrase",params[0],"newpassphrase",params[1])); } static char *walletlock(RPCARGS) { - return(0); + return(sglue(0,myinfo,coin,remoteaddr,"ramchain","walletlock")); } static char *encryptwallet(RPCARGS) { - return(0); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","encryptwallet","passphrase",params[0])); } static char *checkwallet(RPCARGS) { - return(0); + return(sglue(0,myinfo,coin,remoteaddr,"ramchain","checkwallet")); } static char *repairwallet(RPCARGS) { - return(0); + return(sglue(0,myinfo,coin,remoteaddr,"ramchain","repairwallet")); } static char *backupwallet(RPCARGS) { - return(0); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","backupwallet","filename",params[0])); } // messages static char *signmessage(RPCARGS) { - return(0); + return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","signmessage","address",params[0],"message",params[1])); } static char *verifymessage(RPCARGS) { - return(0); + return(sglue3(0,myinfo,coin,remoteaddr,"ramchain","verifymessage","address",params[0],"sig",params[1],"message",params[2])); } // unspents static char *listunspent(RPCARGS) { - return(0); + return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","listunspent","minconf",params[0],"maxconf",params[1])); } static char *lockunspent(RPCARGS) { - return(0); + return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","lockunspent","unlock",params[0],"array",params[1])); } static char *listlockunspent(RPCARGS) { - return(0); + return(sglue(0,myinfo,coin,remoteaddr,"ramchain","listlockunspent")); } static char *gettxout(RPCARGS) { - return(0); + return(sglue3(0,myinfo,coin,remoteaddr,"ramchain","gettxout","txid",params[0],"vout",params[1],"mempool",params[2])); } static char *gettxoutsetinfo(RPCARGS) { - return(0); + return(sglue(0,myinfo,coin,remoteaddr,"ramchain","gettxoutsetinfo")); } // payments static char *sendtoaddress(RPCARGS) { - char *coinaddr,*comment=0,*comment2=0; double amount = -1.; - //sendtoaddress [comment] [comment-to] is a real and is rounded to 8 decimal places. Returns the transaction ID if successful. Y - if ( params[0] != 0 && (coinaddr= jstr(params[0],0)) != 0 && params[1] != 0 && is_cJSON_Number(params[1]) != 0 ) - { - if ( iguana_addressvalidate(coin,coinaddr) < 0 ) - return(clonestr("{\"error\":\"invalid coin address\"}")); - amount = jdouble(params[1],0); - comment = jstr(params[2],0); - comment2 = jstr(params[3],0); - printf("need to generate send %.8f to %s [%s] [%s]\n",dstr(amount),coinaddr,comment!=0?comment:"",comment2!=0?comment2:""); - } - return(clonestr("{\"error\":\"need address and amount\"}")); + return(sglue4(0,myinfo,coin,remoteaddr,"ramchain","sendtoaddress","address",params[0],"amount",params[1],"comment",params[2],"comment2",params[3])); } static char *movecmd(RPCARGS) { - return(0); + return(sglue5(0,myinfo,coin,remoteaddr,"ramchain","move","fromaccount",params[0],"toaccount",params[1],"amount",params[2],"minconf",params[3],"comment",params[4])); } static char *sendfrom(RPCARGS) { - return(0); + return(sglue6(0,myinfo,coin,remoteaddr,"ramchain","sendfrom","fromaccount",params[0],"toaddress",params[1],"amount",params[2],"minconf",params[3],"comment",params[4],"comment2",params[5])); } static char *sendmany(RPCARGS) { - return(0); + return(sglue4(0,myinfo,coin,remoteaddr,"ramchain","sendmany","fromaccount",params[0],"payments",params[1],"minconf",params[2],"comment",params[3])); } static char *settxfee(RPCARGS) { - return(0); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","settxfee","amount",params[0])); } // rawtransaction static char *getrawtransaction(RPCARGS) { - return(0); + return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","getrawtransaction","txid",params[0],"verbose",params[1])); } static char *createrawtransaction(RPCARGS) { - return(0); + return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","createrawtransaction","vins",params[0],"vouts",params[1])); } static char *decoderawtransaction(RPCARGS) { - return(0); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","decoderawtransaction","rawtx",params[0])); } static char *decodescript(RPCARGS) { - return(0); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","decodescript","script",params[0])); } static char *signrawtransaction(RPCARGS) { - return(0); + return(sglue3(0,myinfo,coin,remoteaddr,"ramchain","signrawtransaction","rawtx",params[0],"vins",params[1],"privkeys",params[2])); } static char *sendrawtransaction(RPCARGS) { - return(0); -} - -static char *resendtx(RPCARGS) -{ - return(0); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","sendrawtransaction","rawtx",params[0])); } static char *getrawchangeaddress(RPCARGS) { - return(0); + return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getrawchangeaddress","account",params[0])); } #define true 1 @@ -999,7 +525,6 @@ struct RPC_info { char *name; char *(*rpcfunc)(RPCARGS); int32_t flag0,flag1; } { "sendrawtransaction", &sendrawtransaction, false, false }, { "checkwallet", &checkwallet, false, true}, { "repairwallet", &repairwallet, false, true}, - { "resendtx", &resendtx, false, true}, { "makekeypair", &makekeypair, false, true}, { "sendalert", &sendalert, false, false}, // @@ -1010,13 +535,15 @@ struct RPC_info { char *name; char *(*rpcfunc)(RPCARGS); int32_t flag0,flag1; } { "listlockunspent", &listlockunspent, false, false}, { "lockunspent", &lockunspent, false, false}, { "gettxout", &gettxout, false, false}, - { "gettxoutsetinfo", &gettxoutsetinfo, false, false} + { "gettxoutsetinfo", &gettxoutsetinfo, false, false}, + { "vanitygen", &vanitygen, false, false} #ifdef PEGGY //{ "peggytx", &peggytx, true, false }, //{ "peggypayments", &peggypayments, true, false }, //{ "getpeggyblock", &getpeggyblock, true, false }, #endif - // { "addredeemscript", &addredeemscript, false, false }, + //{ "resendtx", &resendtx, false, true}, + // { "addredeemscript", &addredeemscript, false, false }, // { "getrawmempool", &getrawmempool, true, false }, // { "getdifficulty", &getdifficulty, true, false }, // { "getsubsidy", &getsubsidy, true, false }, diff --git a/iguana/iguana_tx.c b/iguana/iguana_tx.c new file mode 100755 index 000000000..5543619ae --- /dev/null +++ b/iguana/iguana_tx.c @@ -0,0 +1,119 @@ +/****************************************************************************** + * Copyright © 2014-2015 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#include "iguana777.h" +#include "SuperNET.h" + +char *iguana_getrawchangeaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *account) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + +char *iguana_settxfee(struct supernet_info *myinfo,struct iguana_info *coin,double amount) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_listtransactions(struct supernet_info *myinfo,struct iguana_info *coin,char *account,int32_t count,int32_t from) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_listunspent(struct supernet_info *myinfo,struct iguana_info *coin,int32_t minconf,int32_t maxconf) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_lockunspent(struct supernet_info *myinfo,struct iguana_info *coin,char *filename) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_listlockunspent(struct supernet_info *myinfo,struct iguana_info *coin,char *unlock,cJSON *array) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_gettxout(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid,int32_t vout,int32_t mempool) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_gettxoutsetinfo(struct supernet_info *myinfo,struct iguana_info *coin) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_getrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid,int32_t verbose) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_createrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *vins,cJSON *vouts) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_decoderawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *rawtx) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_decodescript(struct supernet_info *myinfo,struct iguana_info *coin,char *script) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *rawtx,cJSON *vins,cJSON *privkeys) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_sendrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *rawtx) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_sendtoaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *address,double amount,char *comment,char *comment2) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_getreceivedbyaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *address,int32_t minconf) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_listreceivedbyaddress(struct supernet_info *myinfo,struct iguana_info *coin,int32_t minconf,int32_t includeempty) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + diff --git a/iguana/iguana_wallet.c b/iguana/iguana_wallet.c index b957b25c1..0dd618ea1 100755 --- a/iguana/iguana_wallet.c +++ b/iguana/iguana_wallet.c @@ -54,3 +54,257 @@ struct iguana_waccount *iguana_waddressfind(struct iguana_info *coin,int32_t *in return(0); } +int32_t iguana_addressvalidate(struct iguana_info *coin,char *coinaddr) +{ + return(0); +} + +char *getnewaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *account) +{ + struct iguana_waddress addr; char str[67]; cJSON *retjson = cJSON_CreateObject(); + if ( iguana_waddresscalc(coin,&addr,rand256(1)) == 0 ) + { + jaddstr(retjson,"result",addr.coinaddr); + init_hexbytes_noT(str,addr.pubkey,33); + jaddstr(retjson,"pubkey",str); + jaddstr(retjson,"privkey",bits256_str(str,addr.privkey)); + jaddstr(retjson,"wip",addr.wipstr); + init_hexbytes_noT(str,addr.rmd160,20); + jaddstr(retjson,"rmd160",str); + if ( iguana_waccountadd(coin,account,&addr) < 0 ) + jaddstr(retjson,"account","error adding to account"); + else jaddstr(retjson,"account",account); + } else jaddstr(retjson,"error","cant create address"); + return(jprint(retjson,1)); +} + +char *getaccountaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *account) +{ + struct iguana_waccount *wacct; struct iguana_waddress *waddr=0,addr; char str[67];cJSON *retjson; + if ( account != 0 && account[0] != 0 ) + { + if ( (wacct= iguana_waccountfind(coin,account)) == 0 ) + { + if ( (waddr= iguana_waddresscalc(coin,&addr,rand256(1))) == 0 ) + return(clonestr("{\"error\":\"cant generate address\"}")); + iguana_waccountswitch(coin,account,0,-1,addr.coinaddr); + } + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result",waddr->coinaddr); + init_hexbytes_noT(str,addr.pubkey,33); + jaddstr(retjson,"pubkey",str); + jaddstr(retjson,"privkey",bits256_str(str,waddr->privkey)); + jaddstr(retjson,"wip",waddr->wipstr); + init_hexbytes_noT(str,waddr->rmd160,20); + jaddstr(retjson,"rmd160",str); + jaddstr(retjson,"account",account); + return(jprint(retjson,1)); + } + return(clonestr("{\"error\":\"no account specified\"}")); +} + +char *setaccount(struct supernet_info *myinfo,struct iguana_info *coin,char *account,char *coinaddr) +{ + struct iguana_waccount *wacct; struct iguana_waddress *waddr=0,addr; int32_t ind=-1; + if ( coinaddr != 0 && coinaddr[0] != 0 && account != 0 && account[0] != 0 ) + { + if ( iguana_addressvalidate(coin,coinaddr) < 0 ) + return(clonestr("{\"error\":\"invalid coin address\"}")); + if ( (wacct= iguana_waddressfind(coin,&ind,coinaddr)) == 0 ) + { + if ( (waddr= iguana_waddresscalc(coin,&addr,rand256(1))) == 0 ) + return(clonestr("{\"error\":\"cant generate address\"}")); + } + iguana_waccountswitch(coin,account,wacct,ind,coinaddr); + return(clonestr("{\"result\":\"account set\"}")); + } + return(clonestr("{\"error\":\"need address and account\"}")); +} + +char *getaccount(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr) +{ + struct iguana_waccount *wacct; cJSON *retjson; int32_t ind; + if ( iguana_addressvalidate(coin,coinaddr) < 0 ) + return(clonestr("{\"error\":\"invalid coin address\"}")); + if ( (wacct= iguana_waddressfind(coin,&ind,coinaddr)) == 0 ) + return(clonestr("{\"result\":\"no account for address\"}")); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result",wacct->account); + return(jprint(retjson,1)); +} + +char *getaddressesbyaccount(struct supernet_info *myinfo,struct iguana_info *coin,char *account) +{ + struct iguana_waccount *subset; struct iguana_waddress *waddr,*tmp; cJSON *retjson,*array; + retjson = cJSON_CreateObject(); + array = cJSON_CreateArray(); + if ( (subset= iguana_waccountfind(coin,account)) != 0 ) + { + HASH_ITER(hh,subset->waddrs,waddr,tmp) + { + jaddistr(array,waddr->coinaddr); + } + } else jaddstr(retjson,"result","cant find account"); + jadd(retjson,"addresses",array); + return(jprint(retjson,1)); +} + +char *sendtoaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,double amount,char *comment,char *comment2) +{ + //char *coinaddr; + //sendtoaddress [comment] [comment-to] is a real and is rounded to 8 decimal places. Returns the transaction ID if successful. Y + if ( coinaddr != 0 && coinaddr[0] != 0 && amount > 0. ) + { + if ( iguana_addressvalidate(coin,coinaddr) < 0 ) + return(clonestr("{\"error\":\"invalid coin address\"}")); + //amount = jdouble(params[1],0); + //comment = jstr(params[2],0); + //comment2 = jstr(params[3],0); + printf("need to generate send %.8f to %s [%s] [%s]\n",dstr(amount),coinaddr,comment!=0?comment:"",comment2!=0?comment2:""); + } + return(clonestr("{\"error\":\"need address and amount\"}")); +} + +char *iguana_getreceivedbyaccount(struct supernet_info *myinfo,struct iguana_info *coin,char *account,int32_t minconf) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_listreceivedbyaccount(struct supernet_info *myinfo,struct iguana_info *coin,char *account,int32_t includeempty) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + + +char *iguana_getaccountaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *account) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_setaccount(struct supernet_info *myinfo,struct iguana_info *coin,char *account) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_getaccount(struct supernet_info *myinfo,struct iguana_info *coin,char *account) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_getaddressesbyaccount(struct supernet_info *myinfo,struct iguana_info *coin,char *account) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_listaddressgroupings(struct supernet_info *myinfo,struct iguana_info *coin) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_getbalance(struct supernet_info *myinfo,struct iguana_info *coin,char *account,int32_t minconf) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_listaccounts(struct supernet_info *myinfo,struct iguana_info *coin,int32_t minconf) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + + +char *iguana_move(struct supernet_info *myinfo,struct iguana_info *coin,char *fromaccount,char *toaccount,double amount,int32_t minconf,char *comment) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_sendfrom(struct supernet_info *myinfo,struct iguana_info *coin,char *fromaccount,char *toaddress,double amount,int32_t minconf,char *comment,char *comment2) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_sendmany(struct supernet_info *myinfo,struct iguana_info *coin,char *fromaccount,cJSON *payments,int32_t minconf,char *comment) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + + +char *iguana_dumpprivkey(struct supernet_info *myinfo,struct iguana_info *coin,char *address) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_importprivkey(struct supernet_info *myinfo,struct iguana_info *coin,char *wip) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_dumpwallet(struct supernet_info *myinfo,struct iguana_info *coin) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_importwallet(struct supernet_info *myinfo,struct iguana_info *coin,char *wallet) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_walletpassphrase(struct supernet_info *myinfo,struct iguana_info *coin,char *passphrase,int32_t timeout) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_walletpassphrasechange(struct supernet_info *myinfo,struct iguana_info *coin,char *oldpassphrase,char *newpassphrase) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_walletlock(struct supernet_info *myinfo,struct iguana_info *coin) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_encryptwallet(struct supernet_info *myinfo,struct iguana_info *coin,char *passphrase) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_checkwallet(struct supernet_info *myinfo,struct iguana_info *coin) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_repairwallet(struct supernet_info *myinfo,struct iguana_info *coin) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + +char *iguana_backupwallet(struct supernet_info *myinfo,struct iguana_info *coin,char *filename) +{ + return(clonestr("{\"error\":\"notyet\"}")); +} + + + + diff --git a/iguana/main.c b/iguana/main.c index 0a7625c07..a18d02b6e 100644 --- a/iguana/main.c +++ b/iguana/main.c @@ -24,6 +24,8 @@ #include "iguana777.h" #include "SuperNET.h" +#define SUPERNET_HELPSTR "SuperNET help text here" + // ALL globals must be here! struct iguana_info *Coins[IGUANA_MAXCOINS]; int32_t USE_JAY,FIRST_EXTERNAL,IGUANA_disableNXT,Debuglevel; @@ -94,7 +96,7 @@ char *pangea_parser(struct supernet_info *myinfo,char *method,cJSON *json,char * char *SuperNET_jsonstr(struct supernet_info *myinfo,char *jsonstr,char *remoteaddr) { - cJSON *json; char *agent,*method,*symbol; + cJSON *json,*retjson; char *agent,*method,*symbol; if ( (json= cJSON_Parse(jsonstr)) != 0 ) { method = jstr(json,"method"); @@ -119,6 +121,12 @@ char *SuperNET_jsonstr(struct supernet_info *myinfo,char *jsonstr,char *remotead strcpy(myinfo->rpcsymbol,symbol); return(clonestr("{\"result\":\"set bitcoin RPC coin\"}")); } + else if ( strcmp(method,"help") == 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result",SUPERNET_HELPSTR); + return(jprint(retjson,1)); + } return(clonestr("{\"error\":\"unrecognized SuperNET method\"}")); } } @@ -174,7 +182,7 @@ char *iguana_blockingjsonstr(struct supernet_info *myinfo,char *jsonstr,uint64_t usleep(100); if ( retjsonstr != 0 ) { - printf("blocking retjsonstr.(%s)\n",retjsonstr); + //printf("blocking retjsonstr.(%s)\n",retjsonstr); queue_delete(&finishedQ,&ptr->DL,allocsize,1); return(retjsonstr); } @@ -210,14 +218,14 @@ char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr) jsonstr = jprint(json,0); if ( (retjsonstr= iguana_blockingjsonstr(myinfo,jsonstr,tag,timeout,remoteaddr)) != 0 ) { - //printf("retjsonstr.(%s)\n",retjsonstr); - if ( (retjson= cJSON_Parse(retjsonstr)) == 0 ) - retjson = cJSON_Parse("{\"error\":\"cant parse retjsonstr\"}"); - jdelete(retjson,"tag"); - jadd64bits(retjson,"tag",tag); - retstr = jprint(retjson,1); - //printf("retstr.(%s) retjsonstr.%p retjson.%p\n",retstr,retjsonstr,retjson); - free(retjsonstr);//,strlen(retjsonstr)+1); + if ( (retjson= cJSON_Parse(retjsonstr)) != 0 ) + { + jdelete(retjson,"tag"); + jadd64bits(retjson,"tag",tag); + retstr = jprint(retjson,1); + //printf("retstr.(%s) retjsonstr.%p retjson.%p\n",retstr,retjsonstr,retjson); + free(retjsonstr);//,strlen(retjsonstr)+1); + } else retstr = retjsonstr; } free(jsonstr); } else retstr = clonestr("{\"error\":\"cant parse JSON\"}"); diff --git a/includes/cJSON.h b/includes/cJSON.h index e682511d8..4e7d8a40d 100755 --- a/includes/cJSON.h +++ b/includes/cJSON.h @@ -186,7 +186,8 @@ extern "C" void jaddi64bits(cJSON *json,uint64_t nxt64bits); void jdelete(cJSON *object,char *string); cJSON *jduplicate(cJSON *json); - + int32_t jnum(cJSON *obj,char *field); + bits256 jbits256(cJSON *json,char *field); bits256 jbits256i(cJSON *json,int32_t i); void jaddbits256(cJSON *json,char *field,bits256 hash);