Browse Source

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
pull/4/head
Mihailo Milenkovic 5 years ago
committed by GitHub
parent
commit
0edf474beb
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 78
      src/base58.cpp
  2. 31
      src/base58.h
  3. 4
      src/cc/CCGateways.h
  4. 2
      src/cc/CCinclude.h
  5. 22
      src/cc/CCutils.cpp
  6. 92
      src/cc/dapps/oraclefeed.c
  7. 192
      src/cc/gateways.cpp
  8. 13
      src/key_io.cpp
  9. 1
      src/key_io.h
  10. 2
      src/rpc/server.cpp
  11. 2
      src/rpc/server.h
  12. 55
      src/wallet/rpcwallet.cpp

78
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());

31
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 &params) const;
@ -151,6 +151,31 @@ public:
bool IsScript() const;
};
class CCustomBitcoinAddress : public CBitcoinAddress {
std::vector<unsigned char> 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
*/

4
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<CPubKey> 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<CPubKey> 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::vector<uint8_t>proof,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

2
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<CPubKey>& 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<std::vector<unsigned char>> &preConditions, std::vector<std::vector<unsigned char>> &params);
@ -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<uint8_t> Mypubkey();
bool Myprivkey(uint8_t myprivkey[]);
int64_t CCduration(int32_t &numblocks,uint256 txid);

22
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<std::vector<unsigned char>> &preConditions, std::vector<std::vector<unsigned char>> &params)
{
@ -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;

92
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;

192
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<CPubKey> 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<CPubKey> 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<CPubKey> 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<CPubKey> &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<CPubKey> &gatewaypubkeys,uint8_t &taddr,uint8_t &prefix,uint8_t &prefix2,uint8_t wiftype)
{
std::vector<uint8_t> vopret; uint8_t *script,e,f,tokenevalcode;
std::vector<uint8_t> vOpretExtra; std::vector<CPubKey> 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<uint8_t> &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::vector<uint8_t>proof,uint256 merkleroot,CPubKey destpub)
int64_t GatewaysVerify(char *refdepositaddr,uint256 oracletxid,int32_t claimvout,std::string refcoin,uint256 cointxid,const std::string deposithex,std::vector<uint8_t>proof,uint256 merkleroot,CPubKey destpub,uint8_t taddr,uint8_t prefix,uint8_t prefix2)
{
std::vector<uint256> 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<numvouts; i++)
{
Getscriptaddress(destaddr,tx.vout[i].scriptPubKey);
GetCustomscriptaddress(destaddr,tx.vout[i].scriptPubKey,taddr,prefix,prefix2);
if ( strcmp(refdepositaddr,destaddr) == 0 )
{
txid = tx.GetHash();
@ -521,13 +527,13 @@ int64_t GatewaysVerify(char *refdepositaddr,uint256 oracletxid,int32_t claimvout
break;
}
}
if ( txid == cointxid )
{
LogPrint("gatewayscc","verified proof for cointxid in merkleroot\n");
return(nValue);
} else LogPrint("gatewayscc","(%s) != (%s) or txid %s mismatch.%d or script mismatch\n",refdepositaddr,destaddr,uint256_str(str,txid),txid != cointxid);
} else LogPrint("gatewayscc","claimaddr.(%s) != destpubaddr.(%s)\n",claimaddr,destpubaddr);
}
if ( txid == cointxid )
{
LogPrint("gatewayscc","verified proof for cointxid in merkleroot\n");
return(nValue);
} else LogPrint("gatewayscc","(%s) != (%s) or txid %s mismatch.%d or script mismatch\n",refdepositaddr,destaddr,uint256_str(str,txid),txid != cointxid);
}
return(0);
}
@ -549,7 +555,7 @@ int64_t GatewaysDepositval(CTransaction tx,CPubKey mypk)
int32_t GatewaysBindExists(struct CCcontract_info *cp,CPubKey gatewayspk,uint256 reftokenid)
{
char markeraddr[64],depositaddr[64]; std::string coin; int32_t numvouts; int64_t totalsupply; uint256 tokenid,oracletxid,hashBlock;
uint8_t M,N,taddr,prefix,prefix2; std::vector<CPubKey> pubkeys; CTransaction tx;
uint8_t M,N,taddr,prefix,prefix2,wiftype; std::vector<CPubKey> pubkeys; CTransaction tx;
std::vector<std::pair<CAddressIndexKey, CAmount> > 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<uint256> txids; std::vector<CPubKey> pubkeys,publishers,tmppublishers; std::vector<uint8_t> 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<CPubKey> pubkeys;
CTransaction vintx,bindtx; int32_t vout,numvouts,n = 0; uint8_t M,N,evalcode,funcid,taddr,prefix,prefix2,wiftype; std::vector<CPubKey> pubkeys;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > 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<CPubKey> 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<CPubKey> 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<CPubKey> pubkeys,publishers; std::vector<uint256>txids; 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<CPubKey> msigpubkeys,publishers; int64_t totalsupply,depositamount,tmpamount,inputs,CCchange=0;
int32_t numvouts,claimvout,height; std::vector<uint8_t> proof;
uint256 hashBlock,tokenid,oracletxid,tmptxid,cointxid; char str[65],depositaddr[64],coinaddr[64],destaddr[64]; std::vector<uint256> 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<CPubKey> msigpubkeys; char depositaddr[64],str[65],coinaddr[64]; struct CCcontract_info *cp,C,*cpTokens,CTokens;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > 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<std::pair<CAddressUnspentKey, CAddressUnspentValue> > 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<CPubKey> pubkeys;
uint8_t K=0,M,N,taddr,prefix,prefix2,wiftype; std::vector<CPubKey> 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<CPubKey> pubkeys;
uint8_t K=0,M,N,taddr,prefix,prefix2,wiftype; std::vector<CPubKey> 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<CPubKey> pubkeys; int64_t amount,totalsupply; CPubKey withdrawpub;
uint8_t K,M,N,taddr,prefix,prefix2,wiftype; std::vector<CPubKey> 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<CPubKey> pubkeys,publishers; std::vector<uint256> 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<uint8_t> proof;
int32_t numvouts,vout,claimvout,height; int64_t totalsupply,nValue,amount; struct CCcontract_info *cp,C;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > 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<CPubKey> msigpubkeys; uint256 hashBlock,tokenid,txid,tmpbindtxid,tmptokenid,oracletxid,withdrawtxid; uint8_t K,M,N,taddr,prefix,prefix2;
std::vector<CPubKey> 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<std::pair<CAddressUnspentKey, CAddressUnspentValue> > 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<CPubKey> 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<std::pair<CAddressUnspentKey, CAddressUnspentValue> > 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<std::pair<CAddressIndexKey, CAmount> > 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<CPubKey> pubkeys;
UniValue result(UniValue::VARR); std::vector<std::pair<CAddressIndexKey, CAmount> > 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<CPubKey> pubkeys;
cp = CCinit(&C,EVAL_GATEWAYS);
SetCCtxids(addressIndex,cp->unspendableCCaddr);
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::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<CPubKey> 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<CPubKey> 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<CPubKey> pubkeys; uint8_t taddr,prefix,prefix2; uint256 tokenid,oracletxid,hashBlock; CTransaction tx;
uint8_t M,N; std::vector<CPubKey> 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<CPubKey> 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 )
{

13
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<unsigned char> data = std::vector<unsigned char>(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;

1
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);

2
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 },

2
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);

55
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<CKeyID>(&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<CPubKey> pubkeys; uint8_t M,N; std::string hex,coin; std::vector<unsigned char> 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<CPubKey> pubkeys;
uint8_t M,N,p1,p2,p3,p4=0; std::string hex,coin; std::vector<unsigned char> 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 )
{

Loading…
Cancel
Save