From 0edf474beb3ae206c0d6f03a2cb937768a023572 Mon Sep 17 00:00:00 2001 From: Mihailo Milenkovic Date: Mon, 11 Feb 2019 16:37:28 +0100 Subject: [PATCH] Multi coin support for GatewaysCC (#18) - Added support for other cions - New RPC for getting address for a pubkey on external chain and for dumping private key in external chain format --- src/base58.cpp | 78 ++++++++++++++++ src/base58.h | 31 +++++- src/cc/CCGateways.h | 4 +- src/cc/CCinclude.h | 2 + src/cc/CCutils.cpp | 22 +++++ src/cc/dapps/oraclefeed.c | 92 +++++++++--------- src/cc/gateways.cpp | 192 +++++++++++++++++++++++++------------- src/key_io.cpp | 13 +++ src/key_io.h | 1 + src/rpc/server.cpp | 2 + src/rpc/server.h | 2 + src/wallet/rpcwallet.cpp | 55 ++++++++++- 12 files changed, 372 insertions(+), 122 deletions(-) diff --git a/src/base58.cpp b/src/base58.cpp index 9d10b7e6a..33b43d745 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -336,6 +336,84 @@ bool CBitcoinAddress::IsScript() const return IsValid() && vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS); } +bool CCustomBitcoinAddress::Set(const CKeyID& id) +{ + SetData(base58Prefixes[0], &id, 20); + return true; +} + +bool CCustomBitcoinAddress::Set(const CPubKey& key) +{ + CKeyID id = key.GetID(); + SetData(base58Prefixes[0], &id, 20); + return true; +} + +bool CCustomBitcoinAddress::Set(const CScriptID& id) +{ + SetData(base58Prefixes[1], &id, 20); + return true; +} + +bool CCustomBitcoinAddress::Set(const CTxDestination& dest) +{ + return boost::apply_visitor(CBitcoinAddressVisitor(this), dest); +} + +bool CCustomBitcoinAddress::IsValid() const +{ + bool fCorrectSize = vchData.size() == 20; + bool fKnownVersion = vchVersion == base58Prefixes[0] || + vchVersion == base58Prefixes[1]; + return fCorrectSize && fKnownVersion; +} + +bool CCustomBitcoinAddress::GetKeyID(CKeyID& keyID) const +{ + if (!IsValid() || vchVersion != base58Prefixes[0]) + return false; + uint160 id; + memcpy(&id, &vchData[0], 20); + keyID = CKeyID(id); + return true; +} + +CTxDestination CCustomBitcoinAddress::Get() const +{ + if (!IsValid()) + return CNoDestination(); + uint160 id; + memcpy(&id, &vchData[0], 20); + if (vchVersion == base58Prefixes[0]) + return CKeyID(id); + else if (vchVersion == base58Prefixes[1]) + return CScriptID(id); + else + return CNoDestination(); +} + +bool CCustomBitcoinAddress::GetIndexKey(uint160& hashBytes, int& type) const +{ + if (!IsValid()) { + return false; + } else if (vchVersion == base58Prefixes[0]) { + memcpy(&hashBytes, &vchData[0], 20); + type = 1; + return true; + } else if (vchVersion == base58Prefixes[1]) { + memcpy(&hashBytes, &vchData[0], 20); + type = 2; + return true; + } + + return false; +} + +bool CCustomBitcoinAddress::IsScript() const +{ + return IsValid() && vchVersion == base58Prefixes[1]; +} + void CBitcoinSecret::SetKey(const CKey& vchSecret) { assert(vchSecret.IsValid()); diff --git a/src/base58.h b/src/base58.h index 4decb4922..52b3ac5f3 100644 --- a/src/base58.h +++ b/src/base58.h @@ -130,9 +130,9 @@ public: */ class CBitcoinAddress : public CBase58Data { public: - bool Set(const CKeyID &id); - bool Set(const CPubKey &key); - bool Set(const CScriptID &id); + virtual bool Set(const CKeyID &id); + virtual bool Set(const CPubKey &key); + virtual bool Set(const CScriptID &id); bool Set(const CTxDestination &dest); bool IsValid() const; bool IsValid(const CChainParams ¶ms) const; @@ -151,6 +151,31 @@ public: bool IsScript() const; }; +class CCustomBitcoinAddress : public CBitcoinAddress { + std::vector base58Prefixes[2]; +public: + bool Set(const CKeyID &id); + bool Set(const CPubKey &key); + bool Set(const CScriptID &id); + bool Set(const CTxDestination &dest); + bool IsValid() const; + + CCustomBitcoinAddress() {} + CCustomBitcoinAddress(const CTxDestination &dest,uint8_t taddr,uint8_t pubkey_prefix,uint8_t script_prefix) + { + if (taddr!=0) base58Prefixes[0].push_back(taddr); + base58Prefixes[0].push_back(pubkey_prefix); + base58Prefixes[1].push_back(script_prefix); + Set(dest); + } + + CTxDestination Get() const; + bool GetKeyID(CKeyID &keyID) const; + bool GetKeyID_NoCheck(CKeyID& keyID) const; + bool GetIndexKey(uint160& hashBytes, int& type) const; + bool IsScript() const; +}; + /** * A base58-encoded secret key */ diff --git a/src/cc/CCGateways.h b/src/cc/CCGateways.h index 7ecae2228..1f594e38b 100644 --- a/src/cc/CCGateways.h +++ b/src/cc/CCGateways.h @@ -21,7 +21,7 @@ #include "../merkleblock.h" bool GatewaysValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn); -std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t totalsupply,uint256 oracletxid,uint8_t M,uint8_t N,std::vector pubkeys); +std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t totalsupply,uint256 oracletxid,uint8_t M,uint8_t N,std::vector pubkeys,uint8_t p1,uint8_t p2,uint8_t p3,uint8_t p4); std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std::string refcoin,uint256 cointxid,int32_t claimvout,std::string deposithex,std::vectorproof,CPubKey destpub,int64_t amount); std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,uint256 deposittxid,CPubKey destpub,int64_t amount); std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin,CPubKey withdrawpub,int64_t amount); @@ -34,6 +34,8 @@ UniValue GatewaysProcessedWithdraws(uint256 bindtxid,std::string refcoin); // CCcustom UniValue GatewaysInfo(uint256 bindtxid); +UniValue GatewaysExternalAddress(uint256 bindtxid,CPubKey pubkey); +UniValue GatewaysDumpPrivKey(uint256 bindtxid,CKey privkey); UniValue GatewaysList(); #endif diff --git a/src/cc/CCinclude.h b/src/cc/CCinclude.h index 1cb141a16..11af54b66 100644 --- a/src/cc/CCinclude.h +++ b/src/cc/CCinclude.h @@ -151,6 +151,7 @@ int32_t iguana_rwbignum(int32_t rwflag,uint8_t *serialized,int32_t len,uint8_t * CScript GetScriptForMultisig(int nRequired, const std::vector& keys); int64_t CCaddress_balance(char *coinaddr); CPubKey CCtxidaddr(char *txidaddr,uint256 txid); +CPubKey CCCustomtxidaddr(char *txidaddr,uint256 txid,uint8_t taddr,uint8_t prefix,uint8_t prefix2); bool GetCCParams(Eval* eval, const CTransaction &tx, uint32_t nIn, CTransaction &txOut, std::vector> &preConditions, std::vector> ¶ms); @@ -227,6 +228,7 @@ bool GetCCaddress1of2(struct CCcontract_info *cp,char *destaddr,CPubKey pk,CPubK bool ConstrainVout(CTxOut vout,int32_t CCflag,char *cmpaddr,int64_t nValue); bool PreventCC(Eval* eval,const CTransaction &tx,int32_t preventCCvins,int32_t numvins,int32_t preventCCvouts,int32_t numvouts); bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey); +bool GetCustomscriptaddress(char *destaddr,const CScript &scriptPubKey,uint8_t taddr,uint8_t prefix,uint8_t prefix2); std::vector Mypubkey(); bool Myprivkey(uint8_t myprivkey[]); int64_t CCduration(int32_t &numblocks,uint256 txid); diff --git a/src/cc/CCutils.cpp b/src/cc/CCutils.cpp index 6892f6fab..1ee191444 100644 --- a/src/cc/CCutils.cpp +++ b/src/cc/CCutils.cpp @@ -299,6 +299,18 @@ bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey) return(false); } +bool GetCustomscriptaddress(char *destaddr,const CScript &scriptPubKey,uint8_t taddr,uint8_t prefix, uint8_t prefix2) +{ + CTxDestination address; txnouttype whichType; + if ( ExtractDestination(scriptPubKey,address) != 0 ) + { + strcpy(destaddr,(char *)CCustomBitcoinAddress(address,taddr,prefix,prefix2).ToString().c_str()); + return(true); + } + //fprintf(stderr,"ExtractDestination failed\n"); + return(false); +} + bool GetCCParams(Eval* eval, const CTransaction &tx, uint32_t nIn, CTransaction &txOut, std::vector> &preConditions, std::vector> ¶ms) { @@ -359,6 +371,16 @@ CPubKey CCtxidaddr(char *txidaddr,uint256 txid) return(pk); } +CPubKey CCCustomtxidaddr(char *txidaddr,uint256 txid,uint8_t taddr,uint8_t prefix,uint8_t prefix2) +{ + uint8_t buf33[33]; CPubKey pk; + buf33[0] = 0x02; + endiancpy(&buf33[1],(uint8_t *)&txid,32); + pk = buf2pk(buf33); + GetCustomscriptaddress(txidaddr,CScript() << ParseHex(HexStr(pk)) << OP_CHECKSIG,taddr,prefix,prefix2); + return(pk); +} + bool _GetCCaddress(char *destaddr,uint8_t evalcode,CPubKey pk) { CC *payoutCond; diff --git a/src/cc/dapps/oraclefeed.c b/src/cc/dapps/oraclefeed.c index d97df1cd9..cc6b45037 100644 --- a/src/cc/dapps/oraclefeed.c +++ b/src/cc/dapps/oraclefeed.c @@ -312,22 +312,20 @@ uint64_t get_btcusd() char *REFCOIN_CLI; -cJSON *get_komodocli(char *refcoin,char **retstrp,char *acname,char *method,char *arg0,char *arg1,char *arg2,char *arg3) +cJSON *get_cli(char *refcoin,char **retstrp,char *acname,char *method,char *arg0,char *arg1,char *arg2,char *arg3) { long fsize; cJSON *retjson = 0; char cmdstr[32768],*jsonstr,fname[256]; sprintf(fname,"/tmp/oraclefeed.%s",method); if ( acname[0] != 0 ) { - if ( refcoin[0] != 0 && strcmp(refcoin,"KMD") != 0 ) - printf("unexpected: refcoin.(%s) acname.(%s)\n",refcoin,acname); + if ( refcoin[0] == 0 ) + printf("must supply reference coin\n"); sprintf(cmdstr,"./komodo-cli -ac_name=%s %s %s %s %s %s > %s 2>/tmp/oraclefeed.error\n",acname,method,arg0,arg1,arg2,arg3,fname); } - else if ( strcmp(refcoin,"KMD") == 0 ) - sprintf(cmdstr,"./komodo-cli %s %s %s %s %s > %s 2>/tmp/oraclefeed.error\n",method,arg0,arg1,arg2,arg3,fname); else if ( REFCOIN_CLI != 0 && REFCOIN_CLI[0] != 0 ) { sprintf(cmdstr,"%s %s %s %s %s %s > %s 2>/tmp/oraclefeed.error\n",REFCOIN_CLI,method,arg0,arg1,arg2,arg3,fname); - printf("ref.(%s) REFCOIN_CLI (%s)\n",refcoin,cmdstr); + //printf("ref.(%s) REFCOIN_CLI (%s)\n",refcoin,cmdstr); } #ifdef TESTMODE fprintf(stderr,"cmd: %s\n",cmdstr); @@ -349,13 +347,13 @@ cJSON *get_komodocli(char *refcoin,char **retstrp,char *acname,char *method,char return(retjson); } -bits256 komodobroadcast(char *refcoin,char *acname,cJSON *hexjson) +bits256 broadcasttx(char *refcoin,char *acname,cJSON *hexjson) { char *hexstr,*retstr,str[65]; cJSON *retjson; bits256 txid; memset(txid.bytes,0,sizeof(txid)); if ( (hexstr= jstr(hexjson,"hex")) != 0 ) { - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"sendrawtransaction",hexstr,"","","")) != 0 ) + if ( (retjson= get_cli(refcoin,&retstr,acname,"sendrawtransaction",hexstr,"","","")) != 0 ) { if (strcmp("error",jstr(retjson,"result"))==0) printf("%s\n",jstr(retjson,"error")); free_json(retjson); @@ -379,9 +377,9 @@ bits256 sendtoaddress(char *refcoin,char *acname,char *destaddr,int64_t satoshis char numstr[32],*retstr,str[65]; cJSON *retjson; bits256 txid; memset(txid.bytes,0,sizeof(txid)); sprintf(numstr,"%.8f",(double)satoshis/SATOSHIDEN); - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"sendtoaddress",destaddr,numstr,"","")) != 0 ) + if ( (retjson= get_cli(refcoin,&retstr,acname,"sendtoaddress",destaddr,numstr,"","")) != 0 ) { - fprintf(stderr,"unexpected sendrawtransaction json.(%s)\n",jprint(retjson,0)); + fprintf(stderr,"unexpected sendtoaddress json.(%s)\n",jprint(retjson,0)); free_json(retjson); } else if ( retstr != 0 ) @@ -400,10 +398,11 @@ bits256 sendtoaddress(char *refcoin,char *acname,char *destaddr,int64_t satoshis int32_t get_coinheight(char *refcoin,char *acname) { cJSON *retjson; char *retstr; int32_t height=0; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getblockchaininfo","","","","")) != 0 ) + if ( (retjson= get_cli(refcoin,&retstr,acname,"getblockchaininfo","","","","")) != 0 ) { height = jint(retjson,"blocks"); free_json(retjson); + } else if ( retstr != 0 ) { @@ -418,7 +417,7 @@ bits256 get_coinblockhash(char *refcoin,char *acname,int32_t height) cJSON *retjson; char *retstr,heightstr[32]; bits256 hash; memset(hash.bytes,0,sizeof(hash)); sprintf(heightstr,"%d",height); - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getblockhash",heightstr,"","","")) != 0 ) + if ( (retjson= get_cli(refcoin,&retstr,acname,"getblockhash",heightstr,"","","")) != 0 ) { fprintf(stderr,"unexpected blockhash json.(%s)\n",jprint(retjson,0)); free_json(retjson); @@ -439,7 +438,7 @@ bits256 get_coinmerkleroot(char *refcoin,char *acname,bits256 blockhash) { cJSON *retjson; char *retstr,str[65]; bits256 merkleroot; memset(merkleroot.bytes,0,sizeof(merkleroot)); - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getblockheader",bits256_str(str,blockhash),"","","")) != 0 ) + if ( (retjson= get_cli(refcoin,&retstr,acname,"getblockheader",bits256_str(str,blockhash),"","","")) != 0 ) { merkleroot = jbits256(retjson,"merkleroot"); //fprintf(stderr,"got merkleroot.(%s)\n",bits256_str(str,merkleroot)); @@ -477,7 +476,7 @@ int32_t get_coinheader(char *refcoin,char *acname,bits256 *blockhashp,bits256 *m cJSON *get_gatewayspending(char *refcoin,char *acname,char *bindtxidstr) { cJSON *retjson; char *retstr; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"gatewayspendingwithdraws",bindtxidstr,refcoin,"","")) != 0 ) + if ( (retjson= get_cli(refcoin,&retstr,acname,"gatewayspendingwithdraws",bindtxidstr,refcoin,"","")) != 0 ) { //printf("pending.(%s)\n",jprint(retjson,0)); return(retjson); @@ -493,7 +492,7 @@ cJSON *get_gatewayspending(char *refcoin,char *acname,char *bindtxidstr) cJSON *get_gatewaysprocessed(char *refcoin,char *acname,char *bindtxidstr) { cJSON *retjson; char *retstr; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"gatewaysprocessed",bindtxidstr,refcoin,"","")) != 0 ) + if ( (retjson= get_cli(refcoin,&retstr,acname,"gatewaysprocessed",bindtxidstr,refcoin,"","")) != 0 ) { //printf("pending.(%s)\n",jprint(retjson,0)); return(retjson); @@ -509,7 +508,7 @@ cJSON *get_gatewaysprocessed(char *refcoin,char *acname,char *bindtxidstr) cJSON *get_rawmempool(char *refcoin,char *acname) { cJSON *retjson; char *retstr; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getrawmempool","","","","")) != 0 ) + if ( (retjson= get_cli(refcoin,&retstr,acname,"getrawmempool","","","","")) != 0 ) { //printf("mempool.(%s)\n",jprint(retjson,0)); return(retjson); @@ -528,7 +527,7 @@ cJSON *get_addressutxos(char *refcoin,char *acname,char *coinaddr) if ( refcoin[0] != 0 && strcmp(refcoin,"KMD") != 0 ) printf("warning: assumes %s has addressindex enabled\n",refcoin); sprintf(jsonbuf,"{\\\"addresses\\\":[\\\"%s\\\"]}",coinaddr); - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getaddressutxos",jsonbuf,"","","")) != 0 ) + if ( (retjson= get_cli(refcoin,&retstr,acname,"getaddressutxos",jsonbuf,"","","")) != 0 ) { //printf("addressutxos.(%s)\n",jprint(retjson,0)); return(retjson); @@ -544,7 +543,7 @@ cJSON *get_addressutxos(char *refcoin,char *acname,char *coinaddr) cJSON *get_rawtransaction(char *refcoin,char *acname,bits256 txid) { cJSON *retjson; char *retstr,str[65]; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getrawtransaction",bits256_str(str,txid),"1","","")) != 0 ) + if ( (retjson= get_cli(refcoin,&retstr,acname,"getrawtransaction",bits256_str(str,txid),"1","","")) != 0 ) { return(retjson); } @@ -559,7 +558,7 @@ cJSON *get_rawtransaction(char *refcoin,char *acname,bits256 txid) int32_t validateaddress(char *refcoin,char *acname,char *depositaddr, char* compare) { cJSON *retjson; char *retstr; int32_t res=0; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"validateaddress",depositaddr,"","","")) != 0 ) + if ( (retjson= get_cli(refcoin,&retstr,acname,"validateaddress",depositaddr,"","","")) != 0 ) { if (is_cJSON_True(jobj(retjson,compare)) != 0 ) res=1; free_json(retjson); @@ -578,7 +577,7 @@ void importaddress(char *refcoin,char *acname,char *depositaddr, char *label,int cJSON *retjson; char *retstr; char rescanstr[10]; if (rescan) strcpy(rescanstr,"true"); else strcpy(rescanstr,"false"); - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"importaddress",depositaddr,label,rescanstr,"")) != 0 ) + if ( (retjson= get_cli(refcoin,&retstr,acname,"importaddress",depositaddr,label,rescanstr,"")) != 0 ) { printf("importaddress.(%s)\n",jprint(retjson,0)); free_json(retjson); @@ -595,7 +594,7 @@ void addmultisigaddress(char *refcoin,char *acname,int32_t M, char *pubkeys) cJSON *retjson; char *retstr,Mstr[10],addr[64]; sprintf(Mstr,"%d",M); - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"addmultisigaddress",Mstr,pubkeys,"","")) != 0 ) + if ( (retjson= get_cli(refcoin,&retstr,acname,"addmultisigaddress",Mstr,pubkeys,"","")) != 0 ) { fprintf(stderr,"unexpected addmultisigaddress json.(%s)\n",jprint(retjson,0)); free(retstr); @@ -603,7 +602,7 @@ void addmultisigaddress(char *refcoin,char *acname,int32_t M, char *pubkeys) else if ( retstr != 0 ) { sprintf(addr,"\"%s\"",retstr); - get_komodocli(refcoin,&retstr,acname,"importaddress",addr,"\"\"","false",""); + get_cli(refcoin,&retstr,acname,"importaddress",addr,"\"\"","false",""); printf("addmultisigaddress.(%s)\n",retstr); free_json(retjson); } @@ -648,7 +647,7 @@ char *createrawtx(char *refcoin,char *acname,char *depositaddr,char *withdrawadd return(0); } sprintf(array,"\'[\"%s\"]\'",depositaddr); - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"listunspent","1","99999999",array,"")) != 0 ) + if ( (retjson= get_cli(refcoin,&retstr,acname,"listunspent","1","99999999",array,"")) != 0 ) { //createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,...} if ( (vins= getinputarray(&total,retjson,satoshis)) != 0 ) @@ -669,7 +668,7 @@ char *createrawtx(char *refcoin,char *acname,char *depositaddr,char *withdrawadd char *argB=malloc(sizeof(char) * (strlen(tmpB)+3)); sprintf(argA,"\'%s\'",tmpA); sprintf(argB,"\'%s\'",tmpB); - if ( (retjson2= get_komodocli(refcoin,&txstr,acname,"createrawtransaction",argA,argB,"","")) != 0 ) + if ( (retjson2= get_cli(refcoin,&txstr,acname,"createrawtransaction",argA,argB,"","")) != 0 ) { printf("createrawtx: unexpected JSON2.(%s)\n",jprint(retjson2,0)); free_json(retjson2); @@ -697,7 +696,7 @@ char *createrawtx(char *refcoin,char *acname,char *depositaddr,char *withdrawadd cJSON *addsignature(char *refcoin,char *acname,char *rawtx, int M) { char *retstr,*hexstr; cJSON *retjson; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"signrawtransaction",rawtx,"","","")) != 0 ) + if ( (retjson= get_cli(refcoin,&retstr,acname,"signrawtransaction",rawtx,"","","")) != 0 ) { if ( is_cJSON_True(jobj(retjson,"complete")) != 0 ) return(retjson); @@ -716,12 +715,12 @@ cJSON *addsignature(char *refcoin,char *acname,char *rawtx, int M) return(0); } -bits256 gatewayspartialsign(char *refcoin,char *acname,bits256 txid,char *coin,char *hex) +bits256 gatewayspartialsign(char *refcoin,char *acname,bits256 txid,char *hex) { char str[65],*retstr; cJSON *retjson; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"gatewayspartialsign",bits256_str(str,txid),coin,hex,"")) != 0 ) + if ( (retjson= get_cli(refcoin,&retstr,acname,"gatewayspartialsign",bits256_str(str,txid),refcoin,hex,"")) != 0 ) { - if (strcmp("error",jstr(retjson,"result"))!=0) txid=komodobroadcast(refcoin,acname,retjson); + if (strcmp("error",jstr(retjson,"result"))!=0) txid=broadcasttx(refcoin,acname,retjson); else printf("%s\n",jstr(retjson,"error")); free(retjson); return (txid); @@ -734,12 +733,12 @@ bits256 gatewayspartialsign(char *refcoin,char *acname,bits256 txid,char *coin,c return (zeroid); } -bits256 gatewayscompletesigning(char *refcoin,char *acname,bits256 withtxid,char *coin,char *hex) +bits256 gatewayscompletesigning(char *refcoin,char *acname,bits256 withtxid,char *hex) { char str[65],*retstr; cJSON *retjson; bits256 txid; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"gatewayscompletesigning",bits256_str(str,withtxid),coin,hex,"")) != 0 ) + if ( (retjson= get_cli(refcoin,&retstr,acname,"gatewayscompletesigning",bits256_str(str,withtxid),refcoin,hex,"")) != 0 ) { - if (strcmp("error",jstr(retjson,"result"))!=0) txid=komodobroadcast(refcoin,acname,retjson); + if (strcmp("error",jstr(retjson,"result"))!=0) txid=broadcasttx(refcoin,acname,retjson); else printf("%s\n",jstr(retjson,"error")); free(retjson); return (txid); @@ -752,12 +751,12 @@ bits256 gatewayscompletesigning(char *refcoin,char *acname,bits256 withtxid,char return (zeroid); } -bits256 gatewaysmarkdone(char *refcoin,char *acname,bits256 withtxid,char *coin) +bits256 gatewaysmarkdone(char *refcoin,char *acname,bits256 withtxid) { char str[65],str2[65],*retstr; cJSON *retjson; bits256 txid; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"gatewaysmarkdone",bits256_str(str,withtxid),coin,"","")) != 0 ) + if ( (retjson= get_cli(refcoin,&retstr,acname,"gatewaysmarkdone",bits256_str(str,withtxid),refcoin,"","")) != 0 ) { - if (strcmp("error",jstr(retjson,"result"))!=0) txid=komodobroadcast(refcoin,acname,retjson); + if (strcmp("error",jstr(retjson,"result"))!=0) txid=broadcasttx(refcoin,acname,retjson); else printf("%s\n",jstr(retjson,"error")); free(retjson); return (txid); @@ -773,7 +772,7 @@ bits256 gatewaysmarkdone(char *refcoin,char *acname,bits256 withtxid,char *coin) int32_t get_gatewaysinfo(char *refcoin,char *acname,char *depositaddr,int32_t *Mp,int32_t *Np,char *bindtxidstr,char *coin,char *oraclestr, char **pubkeys) { char *oracle,*retstr,*name,*deposit,temp[128]; cJSON *retjson,*pubarray; int32_t n; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"gatewaysinfo",bindtxidstr,"","","")) != 0 ) + if ( (retjson= get_cli(refcoin,&retstr,acname,"gatewaysinfo",bindtxidstr,"","","")) != 0 ) { if ( (oracle= jstr(retjson,"oracletxid")) != 0 && strcmp(oracle,oraclestr) == 0 && (deposit= jstr(retjson,"deposit")) != 0 ) { @@ -888,7 +887,7 @@ void update_gatewayspending(char *refcoin,char *acname,char *bindtxidstr,int32_t int32_t i,j,n,K,retval,processed = 0; bits256 txid,cointxid,withdrawtxid,lasttxid,completetxid; int64_t satoshis; memset(&zeroid,0,sizeof(zeroid)); - if ( (retjson= get_gatewayspending("KMD",acname,bindtxidstr)) != 0 ) + if ( (retjson= get_gatewayspending(refcoin,acname,bindtxidstr)) != 0 ) { if ( jint(retjson,"queueflag") != 0 && (coinstr= jstr(retjson,"coin")) != 0 && strcmp(coinstr,refcoin) == 0 ) { @@ -912,7 +911,7 @@ void update_gatewayspending(char *refcoin,char *acname,char *bindtxidstr,int32_t { if ( (clijson=addsignature(refcoin,"",rawtx,M)) != 0 && is_cJSON_True(jobj(clijson,"complete")) != 0) { - txid=gatewayscompletesigning("KMD",acname,withdrawtxid,refcoin,jstr(clijson,"hex")); + txid=gatewayscompletesigning(refcoin,acname,withdrawtxid,jstr(clijson,"hex")); if (txid.txid!=zeroid.txid) fprintf(stderr,"#WITHDRAW (%s) complete signing tx sent - %s\n",bits256_str(str,withdrawtxid),bits256_str(str1,txid)); else fprintf(stderr,"error broadcasting tx on %s",acname); free_json(clijson); @@ -934,13 +933,13 @@ void update_gatewayspending(char *refcoin,char *acname,char *bindtxidstr,int32_t { if ( is_cJSON_True(jobj(clijson,"complete")) != 0 ) { - txid=gatewayscompletesigning("KMD",acname,lasttxid,refcoin,jstr(clijson,"hex")); + txid=gatewayscompletesigning(refcoin,acname,lasttxid,jstr(clijson,"hex")); if (txid.txid!=zeroid.txid) fprintf(stderr,"### SIGNING withdraw %s %dof%d\n",bits256_str(str,withdrawtxid),K+1,N); else fprintf(stderr,"### SIGNING error broadcasting tx on %s\n",acname); } else if ( jint(clijson,"partialtx") != 0 ) { - txid=gatewayspartialsign("KMD",acname,lasttxid,refcoin,jstr(clijson,"hex")); + txid=gatewayspartialsign(refcoin,acname,lasttxid,jstr(clijson,"hex")); if (txid.txid!=zeroid.txid) fprintf(stderr,"### SIGNING withdraw %s %d/%dof%d\n",bits256_str(str,withdrawtxid),K+1,M,N); else fprintf(stderr,"### SIGNING error broadcasting tx on %s\n",acname); } @@ -956,7 +955,7 @@ void update_gatewayspending(char *refcoin,char *acname,char *bindtxidstr,int32_t } free_json(retjson); } - if ( (retjson= get_gatewaysprocessed("KMD",acname,bindtxidstr)) != 0 ) + if ( (retjson= get_gatewaysprocessed(refcoin,acname,bindtxidstr)) != 0 ) { if ( jint(retjson,"queueflag") != 0 && (coinstr= jstr(retjson,"coin")) != 0 && strcmp(coinstr,refcoin) == 0 ) { @@ -973,12 +972,12 @@ void update_gatewayspending(char *refcoin,char *acname,char *bindtxidstr,int32_t importaddress(refcoin,"",txidaddr,jstr(item,"withdrawtxid"),0); if (is_cJSON_True(jobj(item,"confirmed_or_notarized")) && txidaddr != 0 && markerexists(refcoin,"",txidaddr)==0) { - cointxid = komodobroadcast(refcoin,"",item); + cointxid = broadcasttx(refcoin,"",item); if ( bits256_nonz(cointxid) != 0 ) { withdrawaddr = jstr(item,"withdrawaddr"); fprintf(stderr,"### WITHDRAW %.8f %s sent to %s\n",amount,refcoin,withdrawaddr); - txid=gatewaysmarkdone("KMD",acname,completetxid,refcoin); + txid=gatewaysmarkdone(refcoin,acname,completetxid); if (txid.txid!=zeroid.txid) fprintf(stderr,"### MARKDONE withdraw %s\n",bits256_str(str,withdrawtxid)); } else fprintf(stderr,"### WITHDRAW error broadcasting tx on %s\n",refcoin); @@ -1073,7 +1072,7 @@ int32_t main(int32_t argc,char **argv) while ( 1 ) { retstr = 0; - if ( (refcoin[0] == 0 || prevheight < (get_coinheight(refcoin,"") - 10)) && (clijson= get_komodocli("KMD",&retstr,acname,"oraclesinfo",oraclestr,"","","")) != 0 ) + if ( (refcoin[0] == 0 || prevheight < (get_coinheight(refcoin,"") - 10)) && (clijson= get_cli(refcoin,&retstr,acname,"oraclesinfo",oraclestr,"","","")) != 0 ) { if ( refcoin[0] == 0 && jstr(clijson,"name") != 0 ) { @@ -1084,7 +1083,7 @@ int32_t main(int32_t argc,char **argv) exit(0); } pubkeys=0; - if ( get_gatewaysinfo("KMD",acname,depositaddr,&M,&N,bindtxidstr,refcoin,oraclestr,&pubkeys) < 0 ) + if ( get_gatewaysinfo(refcoin,acname,depositaddr,&M,&N,bindtxidstr,refcoin,oraclestr,&pubkeys) < 0 ) { printf("cant find bindtxid.(%s)\n",bindtxidstr); exit(0); @@ -1106,10 +1105,9 @@ int32_t main(int32_t argc,char **argv) { if ( (height= get_oracledata(refcoin,"",prevheight,hexstr,sizeof(hexstr),"Ihh")) != 0 ) { - if ( (clijson2= get_komodocli("KMD",&retstr2,acname,"oraclesdata",oraclestr,hexstr,"","")) != 0 ) + if ( (clijson2= get_cli(refcoin,&retstr2,acname,"oraclesdata",oraclestr,hexstr,"","")) != 0 ) { - //printf("data.(%s)\n",jprint(clijson2,0)); - txid = komodobroadcast("KMD",acname,clijson2); + txid = broadcasttx(refcoin,acname,clijson2); if ( bits256_nonz(txid) != 0 ) { prevheight = height; diff --git a/src/cc/gateways.cpp b/src/cc/gateways.cpp index 5c8de254d..af9038f81 100644 --- a/src/cc/gateways.cpp +++ b/src/cc/gateways.cpp @@ -14,6 +14,7 @@ ******************************************************************************/ #include "CCGateways.h" +#include "key_io.h" /* prevent duplicate bindtxid via mempool scan @@ -147,7 +148,7 @@ */ // start of consensus code -CScript EncodeGatewaysBindOpRet(uint8_t funcid,uint256 tokenid,std::string coin,int64_t totalsupply,uint256 oracletxid,uint8_t M,uint8_t N,std::vector gatewaypubkeys,uint8_t taddr,uint8_t prefix,uint8_t prefix2) +CScript EncodeGatewaysBindOpRet(uint8_t funcid,uint256 tokenid,std::string coin,int64_t totalsupply,uint256 oracletxid,uint8_t M,uint8_t N,std::vector gatewaypubkeys,uint8_t taddr,uint8_t prefix,uint8_t prefix2,uint8_t wiftype) { CScript opret; uint8_t evalcode = EVAL_GATEWAYS; struct CCcontract_info *cp,C; CPubKey gatewayspk; std::vector pubkeys; @@ -155,11 +156,11 @@ CScript EncodeGatewaysBindOpRet(uint8_t funcid,uint256 tokenid,std::string coin, cp = CCinit(&C,EVAL_GATEWAYS); gatewayspk = GetUnspendable(cp,0); pubkeys.push_back(gatewayspk); - opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << coin << totalsupply << oracletxid << M << N << gatewaypubkeys << taddr << prefix << prefix2); + opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << coin << totalsupply << oracletxid << M << N << gatewaypubkeys << taddr << prefix << prefix2 << wiftype); return(EncodeTokenOpRet(tokenid,pubkeys,opret)); } -uint8_t DecodeGatewaysBindOpRet(char *depositaddr,const CScript &scriptPubKey,uint256 &tokenid,std::string &coin,int64_t &totalsupply,uint256 &oracletxid,uint8_t &M,uint8_t &N,std::vector &gatewaypubkeys,uint8_t &taddr,uint8_t &prefix,uint8_t &prefix2) +uint8_t DecodeGatewaysBindOpRet(char *depositaddr,const CScript &scriptPubKey,uint256 &tokenid,std::string &coin,int64_t &totalsupply,uint256 &oracletxid,uint8_t &M,uint8_t &N,std::vector &gatewaypubkeys,uint8_t &taddr,uint8_t &prefix,uint8_t &prefix2,uint8_t wiftype) { std::vector vopret; uint8_t *script,e,f,tokenevalcode; std::vector vOpretExtra; std::vector pubkeys; @@ -171,7 +172,7 @@ uint8_t DecodeGatewaysBindOpRet(char *depositaddr,const CScript &scriptPubKey,ui else GetOpReturnData(scriptPubKey, vopret); script = (uint8_t *)vopret.data(); depositaddr[0] = 0; - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> coin; ss >> totalsupply; ss >> oracletxid; ss >> M; ss >> N; ss >> gatewaypubkeys; ss >> taddr; ss >> prefix; ss >> prefix2;) != 0 ) + if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> coin; ss >> totalsupply; ss >> oracletxid; ss >> M; ss >> N; ss >> gatewaypubkeys; ss >> taddr; ss >> prefix; ss >> prefix2; ss >> wiftype) != 0 ) { if ( prefix == 60 ) { @@ -181,6 +182,11 @@ uint8_t DecodeGatewaysBindOpRet(char *depositaddr,const CScript &scriptPubKey,ui //LogPrint("gatewayscc","f.%c M.%d of N.%d size.%d -> %s\n",f,M,N,(int32_t)gatewaypubkeys.size(),depositaddr); } else Getscriptaddress(depositaddr,CScript() << ParseHex(HexStr(gatewaypubkeys[0])) << OP_CHECKSIG); } + else if (prefix == 28 && prefix2 == 50) + { + if ( N > 1 ) strcpy(depositaddr,CCustomBitcoinAddress(CScriptID(GetScriptForMultisig(M,gatewaypubkeys)),taddr,prefix,prefix2).ToString().c_str()); + else GetCustomscriptaddress(depositaddr,CScript() << ParseHex(HexStr(gatewaypubkeys[0])) << OP_CHECKSIG,taddr,prefix,prefix2); + } else { LogPrint("gatewayscc","need to generate non-KMD addresses prefix.%d\n",prefix); @@ -446,7 +452,7 @@ uint256 GatewaysReverseScan(uint256 &txid,int32_t height,uint256 reforacletxid,u } } //else LogPrint("gatewayscc","height.%d vs search ht.%d\n",(int32_t)merkleht,(int32_t)height); batontxid = bhash; - //LogPrint("gatewayscc","new hash %s\n",uint256_str(str,batontxid)); + // LogPrint("gatewayscc","new hash %s\n",uint256_str(str,batontxid)); } else break; } LogPrint("gatewayscc","end of loop\n"); @@ -479,7 +485,7 @@ uint256 BitcoinGetProofMerkleRoot(const std::vector &proofData, std::ve return merkleBlock.txn.ExtractMatches(txids); } -int64_t GatewaysVerify(char *refdepositaddr,uint256 oracletxid,int32_t claimvout,std::string refcoin,uint256 cointxid,const std::string deposithex,std::vectorproof,uint256 merkleroot,CPubKey destpub) +int64_t GatewaysVerify(char *refdepositaddr,uint256 oracletxid,int32_t claimvout,std::string refcoin,uint256 cointxid,const std::string deposithex,std::vectorproof,uint256 merkleroot,CPubKey destpub,uint8_t taddr,uint8_t prefix,uint8_t prefix2) { std::vector txids; uint256 proofroot,hashBlock,txid = zeroid; CTransaction tx; std::string name,description,format; char destaddr[64],destpubaddr[64],claimaddr[64],str[65],str2[65]; int32_t i,numvouts; int64_t nValue = 0; @@ -507,13 +513,13 @@ int64_t GatewaysVerify(char *refdepositaddr,uint256 oracletxid,int32_t claimvout } if ( DecodeHexTx(tx,deposithex) != 0 ) { - Getscriptaddress(claimaddr,tx.vout[claimvout].scriptPubKey); - Getscriptaddress(destpubaddr,CScript() << ParseHex(HexStr(destpub)) << OP_CHECKSIG); + GetCustomscriptaddress(claimaddr,tx.vout[claimvout].scriptPubKey,taddr,prefix,prefix2); + GetCustomscriptaddress(destpubaddr,CScript() << ParseHex(HexStr(destpub)) << OP_CHECKSIG,taddr,prefix,prefix2); if ( strcmp(claimaddr,destpubaddr) == 0 ) { for (i=0; i pubkeys; CTransaction tx; + uint8_t M,N,taddr,prefix,prefix2,wiftype; std::vector pubkeys; CTransaction tx; std::vector > addressIndex; _GetCCaddress(markeraddr,EVAL_GATEWAYS,gatewayspk); @@ -558,7 +564,7 @@ int32_t GatewaysBindExists(struct CCcontract_info *cp,CPubKey gatewayspk,uint256 { if ( myGetTransaction(it->first.txhash,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 0 && DecodeGatewaysOpRet(tx.vout[numvouts-1].scriptPubKey)=='B' ) { - if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2) == 'B' ) + if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) == 'B' ) { if ( tokenid == reftokenid ) { @@ -574,7 +580,7 @@ int32_t GatewaysBindExists(struct CCcontract_info *cp,CPubKey gatewayspk,uint256 const uint256 &hash = txmempool.GetHash(); if ((numvouts=txmempool.vout.size()) > 0 && DecodeGatewaysOpRet(tx.vout[numvouts-1].scriptPubKey)=='B') - if (DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2) == 'B' && + if (DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) == 'B' && tokenid == reftokenid) return(1); } @@ -584,7 +590,7 @@ int32_t GatewaysBindExists(struct CCcontract_info *cp,CPubKey gatewayspk,uint256 bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx, uint32_t nIn) { - int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numblocks,height,claimvout; bool retval; uint8_t funcid,hash[32],K,M,N,taddr,prefix,prefix2; + int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numblocks,height,claimvout; bool retval; uint8_t funcid,hash[32],K,M,N,taddr,prefix,prefix2,wiftype; char str[65],destaddr[64],depositaddr[65],validationError[512]; std::vector txids; std::vector pubkeys,publishers,tmppublishers; std::vector proof; int64_t fullsupply,totalsupply,amount,tmpamount; uint256 hashblock,txid,bindtxid,deposittxid,withdrawtxid,completetxid,tokenid,tmptokenid,oracletxid,bindtokenid,cointxid,tmptxid,merkleroot,mhash; CTransaction bindtx,tmptx; @@ -615,7 +621,7 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction & //vin.1: CC input of tokens //vout.0: CC vout of gateways tokens to gateways tokens CC address //vout.1: CC vout txfee marker - //vout.n-1: opreturn - 'B' tokenid coin totalsupply oracletxid M N pubkeys taddr prefix prefix2 + //vout.n-1: opreturn - 'B' tokenid coin totalsupply oracletxid M N pubkeys taddr prefix prefix2 wiftype return eval->Invalid("unexpected GatewaysValidate for gatewaysbind!"); break; case 'D': @@ -644,7 +650,7 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction & return eval->Invalid("vout.0 is CC for gatewaysClaim!"); else if (myGetTransaction(bindtxid,tmptx,hashblock) == 0) return eval->Invalid("invalid gatewaysbind txid!"); - else if ((numvouts=tmptx.vout.size()) < 1 || DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,tmprefcoin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2) != 'B') + else if ((numvouts=tmptx.vout.size()) < 1 || DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,tmprefcoin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B') return eval->Invalid("invalid gatewaysbind OP_RETURN data!"); else if (tmprefcoin!=refcoin) return eval->Invalid("refcoin different than in bind tx"); @@ -718,7 +724,7 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction & sprintf(validationError,"couldnt find merkleroot for ht.%d %s oracle.%s m.%d vs n.%d\n",height,tmprefcoin.c_str(),uint256_str(str,oracletxid),m,N); return eval->Invalid(validationError); } - else if (GatewaysVerify(depositaddr,oracletxid,claimvout,tmprefcoin,cointxid,hex,proof,merkleroot,pubkey)!=amount) + else if (GatewaysVerify(depositaddr,oracletxid,claimvout,tmprefcoin,cointxid,hex,proof,merkleroot,pubkey,taddr,prefix,prefix2)!=amount) return eval->Invalid("external deposit not verified\n"); } break; @@ -764,7 +770,7 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction & return eval->Invalid("gatewayswithdraw tx is not yet confirmed(notarised)!"); else if (myGetTransaction(bindtxid,tmptx,hashblock) == 0) return eval->Invalid("invalid gatewaysbind txid!"); - else if ((numvouts=tmptx.vout.size()) < 1 || DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,tmprefcoin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2) != 'B') + else if ((numvouts=tmptx.vout.size()) < 1 || DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,tmprefcoin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B') return eval->Invalid("invalid gatewaysbind OP_RETURN data!"); else if (tmprefcoin!=refcoin) return eval->Invalid("refcoin different than in bind tx"); @@ -808,7 +814,7 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction & return eval->Invalid("gatewayswithdraw tx is not yet confirmed(notarised)!"); else if (myGetTransaction(bindtxid,tmptx,hashblock) == 0) return eval->Invalid("invalid gatewaysbind txid!"); - else if ((numvouts=tmptx.vout.size()) < 1 || DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,tmprefcoin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2) != 'B') + else if ((numvouts=tmptx.vout.size()) < 1 || DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,tmprefcoin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B') return eval->Invalid("invalid gatewaysbind OP_RETURN data!"); else if (tmprefcoin!=refcoin) return eval->Invalid("refcoin different than in bind tx"); @@ -846,7 +852,7 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction & return eval->Invalid("gatewayswithdraw tx is not yet confirmed(notarised)!"); else if (myGetTransaction(bindtxid,tmptx,hashblock) == 0) return eval->Invalid("invalid gatewaysbind txid!"); - else if ((numvouts=tmptx.vout.size()) < 1 || DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,tmprefcoin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2) != 'B') + else if ((numvouts=tmptx.vout.size()) < 1 || DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,tmprefcoin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B') return eval->Invalid("invalid gatewaysbind OP_RETURN data!"); else if (tmprefcoin!=refcoin) return eval->Invalid("refcoin different than in bind tx"); @@ -874,13 +880,13 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction & int64_t AddGatewaysInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint256 bindtxid,int64_t total,int32_t maxinputs) { char coinaddr[64],depositaddr[64]; int64_t threshold,nValue,price,totalinputs = 0,totalsupply,amount; - CTransaction vintx,bindtx; int32_t vout,numvouts,n = 0; uint8_t M,N,evalcode,funcid,taddr,prefix,prefix2; std::vector pubkeys; + CTransaction vintx,bindtx; int32_t vout,numvouts,n = 0; uint8_t M,N,evalcode,funcid,taddr,prefix,prefix2,wiftype; std::vector pubkeys; std::vector > unspentOutputs; std::string refcoin,tmprefcoin; CPubKey withdrawpub,destpub; uint256 tokenid,txid,oracletxid,tmpbindtxid,tmptokenid,deposittxid,hashBlock; if ( GetTransaction(bindtxid,bindtx,hashBlock,false) != 0 ) { - if ((numvouts=bindtx.vout.size())!=0 && DecodeGatewaysBindOpRet(depositaddr,bindtx.vout[numvouts-1].scriptPubKey,tokenid,refcoin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2) == 'B') + if ((numvouts=bindtx.vout.size())!=0 && DecodeGatewaysBindOpRet(depositaddr,bindtx.vout[numvouts-1].scriptPubKey,tokenid,refcoin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) == 'B') { GetTokensCCaddress(cp,coinaddr,pk); SetCCunspents(unspentOutputs,coinaddr); @@ -933,10 +939,10 @@ int64_t AddGatewaysInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP return(0); } -std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t totalsupply,uint256 oracletxid,uint8_t M,uint8_t N,std::vector pubkeys) +std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t totalsupply,uint256 oracletxid,uint8_t M,uint8_t N,std::vector pubkeys,uint8_t p1,uint8_t p2,uint8_t p3,uint8_t p4) { CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - CTransaction oracletx; uint8_t taddr,prefix,prefix2; CPubKey mypk,gatewayspk; CScript opret; uint256 hashBlock; + CTransaction oracletx; uint8_t taddr,prefix,prefix2,wiftype; CPubKey mypk,gatewayspk; CScript opret; uint256 hashBlock; struct CCcontract_info *cp,*cpTokens,C,CTokens; std::string name,description,format; int32_t i,numvouts; int64_t fullsupply; char destaddr[64],coinaddr[64],myTokenCCaddr[64],str[65],*fstr; @@ -944,16 +950,18 @@ std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t cpTokens = CCinit(&CTokens,EVAL_TOKENS); if (coin=="KMD") { - taddr = 0; prefix = 60; prefix2 = 85; + wiftype = 188; + taddr = 0; } else { - LogPrint("gatewayscc","set taddr, prefix, prefix2 for %s\n",coin.c_str()); - taddr = 0; - prefix = 60; - prefix2 = 85; + prefix = p1; + prefix2 = p2; + wiftype = p3; + taddr = p4; + LogPrint("gatewayscc","set prefix %d, prefix2 %d, wiftype %d for %s\n",prefix,prefix2,wiftype,coin.c_str()); } if ( N == 0 || N > 15 || M > N ) { @@ -1030,7 +1038,7 @@ std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t { mtx.vout.push_back(MakeTokensCC1vout(cp->evalcode,totalsupply,gatewayspk)); mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,gatewayspk)); - return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeGatewaysBindOpRet('B',tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2))); + return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeGatewaysBindOpRet('B',tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype))); } } CCerror = strprintf("cant find enough inputs"); @@ -1042,7 +1050,7 @@ std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std:: { CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); CTransaction bindtx; CPubKey mypk; uint256 oracletxid,merkleroot,mhash,hashBlock,tokenid,txid; - int64_t totalsupply; int32_t i,m,n,numvouts; uint8_t M,N,taddr,prefix,prefix2; std::string coin; struct CCcontract_info *cp,C; + int64_t totalsupply; int32_t i,m,n,numvouts; uint8_t M,N,taddr,prefix,prefix2,wiftype; std::string coin; struct CCcontract_info *cp,C; std::vector pubkeys,publishers; std::vectortxids; char str[67],depositaddr[64],txidaddr[64]; cp = CCinit(&C,EVAL_GATEWAYS); @@ -1056,9 +1064,9 @@ std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std:: LogPrint("gatewayscc","%s\n", CCerror.c_str() ); return(""); } - if ( DecodeGatewaysBindOpRet(depositaddr,bindtx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2) != 'B' || refcoin != coin ) + if ( DecodeGatewaysBindOpRet(depositaddr,bindtx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B' || refcoin != coin ) { - CCerror = strprintf("invalid coin - bindtxid %s coin.%n",uint256_str(str,bindtxid),coin.c_str()); + CCerror = strprintf("invalid coin - bindtxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str()); LogPrint("gatewayscc","%s\n", CCerror.c_str() ); return(""); } @@ -1099,7 +1107,7 @@ std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std:: LogPrint("gatewayscc","%s\n", CCerror.c_str() ); return(""); } - if ( GatewaysVerify(depositaddr,oracletxid,claimvout,coin,cointxid,deposithex,proof,merkleroot,destpub) != amount ) + if ( GatewaysVerify(depositaddr,oracletxid,claimvout,coin,cointxid,deposithex,proof,merkleroot,destpub,taddr,prefix,prefix2) != amount ) { CCerror = strprintf("deposittxid didnt validate"); LogPrint("gatewayscc","%s\n", CCerror.c_str() ); @@ -1119,7 +1127,7 @@ std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std:: std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,uint256 deposittxid,CPubKey destpub,int64_t amount) { CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - CTransaction tx; CPubKey mypk,gatewayspk,tmpdestpub; struct CCcontract_info *cp,C; uint8_t M,N,taddr,prefix,prefix2; + CTransaction tx; CPubKey mypk,gatewayspk,tmpdestpub; struct CCcontract_info *cp,C; uint8_t M,N,taddr,prefix,prefix2,wiftype; std::string coin, deposithex; std::vector msigpubkeys,publishers; int64_t totalsupply,depositamount,tmpamount,inputs,CCchange=0; int32_t numvouts,claimvout,height; std::vector proof; uint256 hashBlock,tokenid,oracletxid,tmptxid,cointxid; char str[65],depositaddr[64],coinaddr[64],destaddr[64]; std::vector txids; @@ -1135,7 +1143,7 @@ std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,ui LogPrint("gatewayscc","%s\n", CCerror.c_str() ); return(""); } - if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,msigpubkeys,taddr,prefix,prefix2) != 'B' || coin != refcoin ) + if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,msigpubkeys,taddr,prefix,prefix2,wiftype) != 'B' || coin != refcoin ) { CCerror = strprintf("invalid coin - bindtxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str()); LogPrint("gatewayscc","%s\n", CCerror.c_str() ); @@ -1197,7 +1205,7 @@ std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin { CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); CTransaction tx; CPubKey mypk,gatewayspk,signerpk; uint256 txid,tokenid,hashBlock,oracletxid,tmptokenid,tmpbindtxid,withdrawtxid; int32_t vout,numvouts; - int64_t nValue,totalsupply,inputs,CCchange=0,tmpamount; uint8_t funcid,K,M,N,taddr,prefix,prefix2; std::string coin,hex; + int64_t nValue,totalsupply,inputs,CCchange=0,tmpamount; uint8_t funcid,K,M,N,taddr,prefix,prefix2,wiftype; std::string coin,hex; std::vector msigpubkeys; char depositaddr[64],str[65],coinaddr[64]; struct CCcontract_info *cp,C,*cpTokens,CTokens; std::vector > unspentOutputs; @@ -1214,7 +1222,7 @@ std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin LogPrint("gatewayscc","%s\n", CCerror.c_str() ); return(""); } - if( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,msigpubkeys,taddr,prefix,prefix2) != 'B' || coin != refcoin ) + if( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,msigpubkeys,taddr,prefix,prefix2,wiftype) != 'B' || coin != refcoin ) { CCerror = strprintf("invalid bindtxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str()); LogPrint("gatewayscc","%s\n", CCerror.c_str() ); @@ -1283,7 +1291,7 @@ std::string GatewaysPartialSign(uint64_t txfee,uint256 lasttxid,std::string refc CPubKey mypk,withdrawpub,signerpk,gatewayspk; struct CCcontract_info *cp,C; CTransaction tx,tmptx; std::vector > unspentOutputs; char funcid,str[65],depositaddr[64]; int32_t numvouts; uint256 withdrawtxid,hashBlock,bindtxid,tokenid,oracletxid,tmptokenid; std::string coin,tmphex; int64_t amount,totalsupply; - uint8_t K=0,M,N,taddr,prefix,prefix2; std::vector pubkeys; + uint8_t K=0,M,N,taddr,prefix,prefix2,wiftype; std::vector pubkeys; cp = CCinit(&C,EVAL_GATEWAYS); if ( txfee == 0 ) @@ -1318,7 +1326,7 @@ std::string GatewaysPartialSign(uint64_t txfee,uint256 lasttxid,std::string refc LogPrint("gatewayscc","%s\n", CCerror.c_str() ); return(""); } - else if (DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2) != 'B' + else if (DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B' || refcoin!=coin || tokenid!=tmptokenid) { CCerror = strprintf("invalid bind tx %s",uint256_str(str,bindtxid)); @@ -1359,7 +1367,7 @@ std::string GatewaysPartialSign(uint64_t txfee,uint256 lasttxid,std::string refc LogPrint("gatewayscc","%s\n", CCerror.c_str() ); return(""); } - else if (DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2) != 'B' + else if (DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B' || refcoin!=coin || tokenid!=tmptokenid) { CCerror = strprintf("invalid bind tx %s",uint256_str(str,bindtxid)); @@ -1383,7 +1391,7 @@ std::string GatewaysCompleteSigning(uint64_t txfee,uint256 lasttxid,std::string CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); CPubKey mypk,gatewayspk,signerpk,withdrawpub; struct CCcontract_info *cp,C; char funcid,str[65],depositaddr[64]; int64_t amount,totalsupply; std::string coin,tmphex; CTransaction tx,tmptx; uint256 withdrawtxid,hashBlock,tokenid,tmptokenid,bindtxid,oracletxid; int32_t numvouts; - uint8_t K=0,M,N,taddr,prefix,prefix2; std::vector pubkeys; + uint8_t K=0,M,N,taddr,prefix,prefix2,wiftype; std::vector pubkeys; cp = CCinit(&C,EVAL_GATEWAYS); mypk = pubkey2pk(Mypubkey()); @@ -1418,7 +1426,7 @@ std::string GatewaysCompleteSigning(uint64_t txfee,uint256 lasttxid,std::string LogPrint("gatewayscc","%s\n", CCerror.c_str() ); return(""); } - else if (DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2) != 'B' + else if (DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B' || refcoin!=coin || tokenid!=tmptokenid) { CCerror = strprintf("invalid bind tx %s",uint256_str(str,bindtxid)); @@ -1458,7 +1466,7 @@ std::string GatewaysCompleteSigning(uint64_t txfee,uint256 lasttxid,std::string LogPrint("gatewayscc","%s\n", CCerror.c_str() ); return(""); } - else if (DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2) != 'B' + else if (DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B' || refcoin!=coin || tokenid!=tmptokenid) { CCerror = strprintf("invalid bind tx %s",uint256_str(str,bindtxid)); @@ -1482,7 +1490,7 @@ std::string GatewaysMarkDone(uint64_t txfee,uint256 completetxid,std::string ref CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); CPubKey mypk; struct CCcontract_info *cp,C; char str[65],depositaddr[64]; CTransaction tx; int32_t numvouts; uint256 withdrawtxid,bindtxid,oracletxid,tokenid,tmptokenid,hashBlock; std::string coin,hex; - uint8_t K,M,N,taddr,prefix,prefix2; std::vector pubkeys; int64_t amount,totalsupply; CPubKey withdrawpub; + uint8_t K,M,N,taddr,prefix,prefix2,wiftype; std::vector pubkeys; int64_t amount,totalsupply; CPubKey withdrawpub; cp = CCinit(&C,EVAL_GATEWAYS); mypk = pubkey2pk(Mypubkey()); @@ -1524,7 +1532,7 @@ std::string GatewaysMarkDone(uint64_t txfee,uint256 completetxid,std::string ref LogPrint("gatewayscc","%s\n", CCerror.c_str() ); return(""); } - else if (DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2) != 'B' + else if (DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B' || refcoin!=coin || tokenid!=tmptokenid) { CCerror = strprintf("invalid bind tx %s",uint256_str(str,bindtxid)); @@ -1546,7 +1554,7 @@ UniValue GatewaysPendingDeposits(uint256 bindtxid,std::string refcoin) { UniValue result(UniValue::VOBJ),pending(UniValue::VARR); CTransaction tx; std::string coin,hex,pub; CPubKey mypk,gatewayspk,destpub; std::vector pubkeys,publishers; std::vector txids; - uint256 tmpbindtxid,hashBlock,txid,tokenid,oracletxid,cointxid; uint8_t M,N,taddr,prefix,prefix2; + uint256 tmpbindtxid,hashBlock,txid,tokenid,oracletxid,cointxid; uint8_t M,N,taddr,prefix,prefix2,wiftype; char depositaddr[65],coinaddr[65],str[65],destaddr[65],txidaddr[65]; std::vector proof; int32_t numvouts,vout,claimvout,height; int64_t totalsupply,nValue,amount; struct CCcontract_info *cp,C; std::vector > unspentOutputs; @@ -1561,7 +1569,7 @@ UniValue GatewaysPendingDeposits(uint256 bindtxid,std::string refcoin) LogPrint("gatewayscc","%s\n", CCerror.c_str() ); return(""); } - if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2) != 'B' || refcoin != coin) + if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B' || refcoin != coin) { CCerror = strprintf("invalid bindtxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str()); LogPrint("gatewayscc","%s\n", CCerror.c_str() ); @@ -1583,6 +1591,7 @@ UniValue GatewaysPendingDeposits(uint256 bindtxid,std::string refcoin) CCtxidaddr(txidaddr,txid); obj.push_back(Pair("deposittxidaddr",txidaddr)); _GetCCaddress(destaddr,EVAL_TOKENS,destpub); + obj.push_back(Pair("depositaddr",depositaddr)); obj.push_back(Pair("tokens_destination_address",destaddr)); pub=HexStr(destpub); obj.push_back(Pair("claim_pubkey",pub)); @@ -1599,7 +1608,7 @@ UniValue GatewaysPendingDeposits(uint256 bindtxid,std::string refcoin) UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin) { UniValue result(UniValue::VOBJ),pending(UniValue::VARR); CTransaction tx; std::string coin,hex; CPubKey mypk,gatewayspk,withdrawpub,signerpk; - std::vector msigpubkeys; uint256 hashBlock,tokenid,txid,tmpbindtxid,tmptokenid,oracletxid,withdrawtxid; uint8_t K,M,N,taddr,prefix,prefix2; + std::vector msigpubkeys; uint256 hashBlock,tokenid,txid,tmpbindtxid,tmptokenid,oracletxid,withdrawtxid; uint8_t K,M,N,taddr,prefix,prefix2,wiftype; char funcid,depositaddr[65],coinaddr[65],tokensaddr[65],destaddr[65],str[65],withaddr[65],numstr[32],signeraddr[65],txidaddr[65]; int32_t i,n,numvouts,vout,queueflag; int64_t totalsupply,amount,nValue; struct CCcontract_info *cp,C; std::vector > unspentOutputs; @@ -1615,7 +1624,7 @@ UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin) LogPrint("gatewayscc","%s\n", CCerror.c_str() ); return(""); } - if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,msigpubkeys,taddr,prefix,prefix2) != 'B' || refcoin != coin ) + if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,msigpubkeys,taddr,prefix,prefix2,wiftype) != 'B' || refcoin != coin ) { CCerror = strprintf("invalid bindtxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str()); LogPrint("gatewayscc","%s\n", CCerror.c_str() ); @@ -1651,12 +1660,12 @@ UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin) continue; } Getscriptaddress(destaddr,tx.vout[1].scriptPubKey); - Getscriptaddress(withaddr,CScript() << ParseHex(HexStr(withdrawpub)) << OP_CHECKSIG); + GetCustomscriptaddress(withaddr,CScript() << ParseHex(HexStr(withdrawpub)) << OP_CHECKSIG,taddr,prefix,prefix2); if ( strcmp(destaddr,tokensaddr) == 0 ) { UniValue obj(UniValue::VOBJ); obj.push_back(Pair("withdrawtxid",uint256_str(str,tx.GetHash()))); - CCtxidaddr(txidaddr,tx.GetHash()); + CCCustomtxidaddr(txidaddr,tx.GetHash(),taddr,prefix,prefix2); obj.push_back(Pair("withdrawtxidaddr",txidaddr)); obj.push_back(Pair("withdrawaddr",withaddr)); sprintf(numstr,"%.8f",(double)tx.vout[1].nValue/COIN); @@ -1665,7 +1674,7 @@ UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin) if ( queueflag != 0 ) { obj.push_back(Pair("depositaddr",depositaddr)); - Getscriptaddress(signeraddr,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG); + GetCustomscriptaddress(signeraddr,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG,taddr,prefix,prefix2); obj.push_back(Pair("signeraddr",signeraddr)); } if (N>1) @@ -1688,7 +1697,7 @@ UniValue GatewaysProcessedWithdraws(uint256 bindtxid,std::string refcoin) { UniValue result(UniValue::VOBJ),processed(UniValue::VARR); CTransaction tx; std::string coin,hex; CPubKey mypk,gatewayspk,withdrawpub; std::vector msigpubkeys; - uint256 withdrawtxid,hashBlock,txid,tokenid,tmptokenid,oracletxid; uint8_t K,M,N,taddr,prefix,prefix2; + uint256 withdrawtxid,hashBlock,txid,tokenid,tmptokenid,oracletxid; uint8_t K,M,N,taddr,prefix,prefix2,wiftype; char depositaddr[65],coinaddr[65],str[65],numstr[32],withaddr[65],txidaddr[65]; int32_t i,n,numvouts,vout,queueflag; int64_t totalsupply,nValue,amount; struct CCcontract_info *cp,C; std::vector > unspentOutputs; @@ -1703,7 +1712,7 @@ UniValue GatewaysProcessedWithdraws(uint256 bindtxid,std::string refcoin) LogPrint("gatewayscc","%s\n", CCerror.c_str() ); return(""); } - if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,msigpubkeys,taddr,prefix,prefix2) != 'B' || refcoin != coin) + if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,msigpubkeys,taddr,prefix,prefix2,wiftype) != 'B' || refcoin != coin) { CCerror = strprintf("invalid bindtxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str()); LogPrint("gatewayscc","%s\n", CCerror.c_str() ); @@ -1732,9 +1741,9 @@ UniValue GatewaysProcessedWithdraws(uint256 bindtxid,std::string refcoin) UniValue obj(UniValue::VOBJ); obj.push_back(Pair("completesigningtxid",uint256_str(str,txid))); obj.push_back(Pair("withdrawtxid",uint256_str(str,withdrawtxid))); - CCtxidaddr(txidaddr,withdrawtxid); + CCCustomtxidaddr(txidaddr,withdrawtxid,taddr,prefix,prefix2); obj.push_back(Pair("withdrawtxidaddr",txidaddr)); - Getscriptaddress(withaddr,CScript() << ParseHex(HexStr(withdrawpub)) << OP_CHECKSIG); + GetCustomscriptaddress(withaddr,CScript() << ParseHex(HexStr(withdrawpub)) << OP_CHECKSIG,taddr,prefix,prefix2); obj.push_back(Pair("withdrawaddr",withaddr)); obj.push_back(Pair("confirmed_or_notarized",komodo_txnotarizedconfirmed(txid))); sprintf(numstr,"%.8f",(double)tx.vout[1].nValue/COIN); @@ -1752,7 +1761,7 @@ UniValue GatewaysProcessedWithdraws(uint256 bindtxid,std::string refcoin) UniValue GatewaysList() { - UniValue result(UniValue::VARR); std::vector > addressIndex; struct CCcontract_info *cp,C; uint256 txid,hashBlock,oracletxid,tokenid; CTransaction vintx; std::string coin; int64_t totalsupply; char str[65],depositaddr[64]; uint8_t M,N,taddr,prefix,prefix2; std::vector pubkeys; + UniValue result(UniValue::VARR); std::vector > addressIndex; struct CCcontract_info *cp,C; uint256 txid,hashBlock,oracletxid,tokenid; CTransaction vintx; std::string coin; int64_t totalsupply; char str[65],depositaddr[64]; uint8_t M,N,taddr,prefix,prefix2,wiftype; std::vector pubkeys; cp = CCinit(&C,EVAL_GATEWAYS); SetCCtxids(addressIndex,cp->unspendableCCaddr); for (std::vector >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) @@ -1760,7 +1769,7 @@ UniValue GatewaysList() txid = it->first.txhash; if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) { - if ( vintx.vout.size() > 0 && DecodeGatewaysBindOpRet(depositaddr,vintx.vout[vintx.vout.size()-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2) != 0 ) + if ( vintx.vout.size() > 0 && DecodeGatewaysBindOpRet(depositaddr,vintx.vout[vintx.vout.size()-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 0 ) { result.push_back(uint256_str(str,txid)); } @@ -1769,11 +1778,60 @@ UniValue GatewaysList() return(result); } +UniValue GatewaysExternalAddress(uint256 bindtxid,CPubKey pubkey) +{ + UniValue result(UniValue::VOBJ); struct CCcontract_info *cp,C; uint256 txid,hashBlock,oracletxid,tokenid; CTransaction tx; + std::string coin; int64_t numvouts,totalsupply; char str[65],addr[65],depositaddr[65]; uint8_t M,N,taddr,prefix,prefix2,wiftype; std::vector msigpubkeys; + + cp = CCinit(&C,EVAL_GATEWAYS); + if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 ) + { + CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid)); + LogPrint("gatewayscc","%s\n", CCerror.c_str() ); + return(""); + } + if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,msigpubkeys,taddr,prefix,prefix2,wiftype) != 'B') + { + CCerror = strprintf("invalid bindtxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str()); + LogPrint("gatewayscc","%s\n", CCerror.c_str() ); + return(""); + } + GetCustomscriptaddress(addr,CScript() << ParseHex(HexStr(pubkey)) << OP_CHECKSIG,taddr,prefix,prefix2); + result.push_back(Pair("result","success")); + result.push_back(Pair("address",addr)); + return(result); +} + +UniValue GatewaysDumpPrivKey(uint256 bindtxid,CKey key) +{ + UniValue result(UniValue::VOBJ); struct CCcontract_info *cp,C; uint256 txid,hashBlock,oracletxid,tokenid; CTransaction tx; + std::string coin,priv; int64_t numvouts,totalsupply; char str[65],addr[65],depositaddr[65]; uint8_t M,N,taddr,prefix,prefix2,wiftype; std::vector msigpubkeys; + + cp = CCinit(&C,EVAL_GATEWAYS); + if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 ) + { + CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid)); + LogPrint("gatewayscc","%s\n", CCerror.c_str() ); + return(""); + } + if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,msigpubkeys,taddr,prefix,prefix2,wiftype) != 'B') + { + CCerror = strprintf("invalid bindtxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str()); + LogPrint("gatewayscc","%s\n", CCerror.c_str() ); + return(""); + } + + priv=EncodeCustomSecret(key,wiftype); + result.push_back(Pair("result","success")); + result.push_back(Pair("address",priv.c_str())); + return(result); +} + UniValue GatewaysInfo(uint256 bindtxid) { CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); UniValue result(UniValue::VOBJ),a(UniValue::VARR); std::string coin; char str[67],numstr[65],depositaddr[64],gatewaystokens[64]; - uint8_t M,N; std::vector pubkeys; uint8_t taddr,prefix,prefix2; uint256 tokenid,oracletxid,hashBlock; CTransaction tx; + uint8_t M,N; std::vector pubkeys; uint8_t taddr,prefix,prefix2,wiftype; uint256 tokenid,oracletxid,hashBlock; CTransaction tx; CPubKey Gatewayspk; struct CCcontract_info *cp,C; int32_t i; int64_t numvouts,totalsupply,remaining; std::vector msigpubkeys; cp = CCinit(&C,EVAL_GATEWAYS); @@ -1785,7 +1843,7 @@ UniValue GatewaysInfo(uint256 bindtxid) LogPrint("gatewayscc","%s\n", CCerror.c_str() ); return(""); } - if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,msigpubkeys,taddr,prefix,prefix2) != 'B') + if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,msigpubkeys,taddr,prefix,prefix2,wiftype) != 'B') { CCerror = strprintf("invalid bindtxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str()); LogPrint("gatewayscc","%s\n", CCerror.c_str() ); @@ -1796,7 +1854,7 @@ UniValue GatewaysInfo(uint256 bindtxid) result.push_back(Pair("result","success")); result.push_back(Pair("name","Gateways")); depositaddr[0] = 0; - if ( tx.vout.size() > 0 && DecodeGatewaysBindOpRet(depositaddr,tx.vout[tx.vout.size()-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2) != 0 && M <= N && N > 0 ) + if ( tx.vout.size() > 0 && DecodeGatewaysBindOpRet(depositaddr,tx.vout[tx.vout.size()-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 0 && M <= N && N > 0 ) { if ( N > 1 ) { diff --git a/src/key_io.cpp b/src/key_io.cpp index f04c4da04..1953d9623 100644 --- a/src/key_io.cpp +++ b/src/key_io.cpp @@ -206,6 +206,19 @@ std::string EncodeSecret(const CKey& key) return ret; } +std::string EncodeCustomSecret(const CKey& key,uint8_t secret_key) +{ + assert(key.IsValid()); + std::vector data = std::vector(1,secret_key);; + data.insert(data.end(), key.begin(), key.end()); + if (key.IsCompressed()) { + data.push_back(1); + } + std::string ret = EncodeBase58Check(data); + memory_cleanse(data.data(), data.size()); + return ret; +} + CExtPubKey DecodeExtPubKey(const std::string& str) { CExtPubKey key; diff --git a/src/key_io.h b/src/key_io.h index 3606ad09f..72823d57e 100644 --- a/src/key_io.h +++ b/src/key_io.h @@ -18,6 +18,7 @@ CKey DecodeSecret(const std::string& str); std::string EncodeSecret(const CKey& key); +std::string EncodeCustomSecret(const CKey& key,uint8_t secret_key); CExtKey DecodeExtKey(const std::string& str); std::string EncodeExtKey(const CExtKey& extkey); diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 208b3cf02..96e58b3af 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -470,6 +470,8 @@ static const CRPCCommand vRPCCommands[] = // Gateways { "gateways", "gatewaysaddress", &gatewaysaddress, true }, { "gateways", "gatewayslist", &gatewayslist, true }, + { "gateways", "gatewaysexternaladdress", &gatewaysexternaladdress, true }, + { "gateways", "gatewaysdumpprivkey", &gatewaysdumpprivkey, true }, { "gateways", "gatewaysinfo", &gatewaysinfo, true }, { "gateways", "gatewaysbind", &gatewaysbind, true }, { "gateways", "gatewaysdeposit", &gatewaysdeposit, true }, diff --git a/src/rpc/server.h b/src/rpc/server.h index b812ccc9d..3abc6748c 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -293,6 +293,8 @@ extern UniValue cclib(const UniValue& params, bool fHelp); extern UniValue gatewaysaddress(const UniValue& params, bool fHelp); extern UniValue gatewayslist(const UniValue& params, bool fHelp); extern UniValue gatewaysinfo(const UniValue& params, bool fHelp); +extern UniValue gatewaysdumpprivkey(const UniValue& params, bool fHelp); +extern UniValue gatewaysexternaladdress(const UniValue& params, bool fHelp); extern UniValue gatewaysbind(const UniValue& params, bool fHelp); extern UniValue gatewaysdeposit(const UniValue& params, bool fHelp); extern UniValue gatewaysclaim(const UniValue& params, bool fHelp); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index abd0b9696..b0bdd6bdd 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -6140,6 +6140,47 @@ UniValue gatewayslist(const UniValue& params, bool fHelp) return(GatewaysList()); } +UniValue gatewaysexternaladdress(const UniValue& params, bool fHelp) +{ + uint256 bindtxid; CPubKey pubkey; + + if ( fHelp || params.size() != 2) + throw runtime_error("gatewaysexternaladdress bindtxid pubkey\n"); + if ( ensure_CCrequirements() < 0 ) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + const CKeyStore& keystore = *pwalletMain; + LOCK2(cs_main, pwalletMain->cs_wallet); + bindtxid = Parseuint256((char *)params[0].get_str().c_str()); + pubkey = ParseHex(params[1].get_str().c_str()); + return(GatewaysExternalAddress(bindtxid,pubkey)); +} + +UniValue gatewaysdumpprivkey(const UniValue& params, bool fHelp) +{ + uint256 bindtxid; + + if ( fHelp || params.size() != 2) + throw runtime_error("gatewaysexternaladdress bindtxid address\n"); + if ( ensure_CCrequirements() < 0 ) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + LOCK2(cs_main, pwalletMain->cs_wallet); + bindtxid = Parseuint256((char *)params[0].get_str().c_str()); + std::string strAddress = params[1].get_str(); + CTxDestination dest = DecodeDestination(strAddress); + if (!IsValidDestination(dest)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid transparent address"); + } + const CKeyID *keyID = boost::get(&dest); + if (!keyID) { + throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key"); + } + CKey vchSecret; + if (!pwalletMain->GetKey(*keyID, vchSecret)) { + throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + strAddress + " is not known"); + } + return(GatewaysDumpPrivKey(bindtxid,vchSecret)); +} + UniValue gatewaysinfo(const UniValue& params, bool fHelp) { uint256 txid; @@ -6155,9 +6196,11 @@ UniValue gatewaysinfo(const UniValue& params, bool fHelp) UniValue gatewaysbind(const UniValue& params, bool fHelp) { - UniValue result(UniValue::VOBJ); uint256 tokenid,oracletxid; int32_t i; int64_t totalsupply; std::vector pubkeys; uint8_t M,N; std::string hex,coin; std::vector pubkey; - if ( fHelp || params.size() < 6 ) - throw runtime_error("gatewaysbind tokenid oracletxid coin tokensupply M N pubkey(s)\n"); + UniValue result(UniValue::VOBJ); uint256 tokenid,oracletxid; int32_t i; int64_t totalsupply; std::vector pubkeys; + uint8_t M,N,p1,p2,p3,p4=0; std::string hex,coin; std::vector pubkey; + + if ( fHelp || params.size() < 9 ) + throw runtime_error("gatewaysbind tokenid oracletxid coin tokensupply M N pubkey(s) pubtype p2shtype wiftype [taddr]\n"); if ( ensure_CCrequirements() < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); const CKeyStore& keystore = *pwalletMain; @@ -6179,7 +6222,11 @@ UniValue gatewaysbind(const UniValue& params, bool fHelp) throw runtime_error("invalid destination pubkey"); pubkeys.push_back(pubkey2pk(pubkey)); } - hex = GatewaysBind(0,coin,tokenid,totalsupply,oracletxid,M,N,pubkeys); + p1 = atoi((char *)params[6+N].get_str().c_str()); + p2 = atoi((char *)params[6+N+1].get_str().c_str()); + p3 = atoi((char *)params[6+N+2].get_str().c_str()); + if (params.size() == 9+N) p4 = atoi((char *)params[6+N+3].get_str().c_str()); + hex = GatewaysBind(0,coin,tokenid,totalsupply,oracletxid,M,N,pubkeys,p1,p2,p3,p4); RETURN_IF_ERROR(CCerror); if ( hex.size() > 0 ) {