@ -132,14 +132,18 @@
Implementation Issues :
When thinking about validation , it is clear that we cant use EVAL_ASSETS for the locked coins as there wont be any enforcement of the gateways locking . This means we need a way to transfer assets into gateways outputs and back . It seems a tokenconvert rpc will be needed and hopefully that will be enough to make it all work properly .
- - When thinking about validation , it is clear that we cant use EVAL_ASSETS for the locked coins as there wont be any enforcement of the gateways locking .
- - This means we need a way to transfer assets into gateways outputs and back . It seems a tokenconvert rpc will be needed and hopefully that will be enough to make it all work properly .
+ + The use of tokenconvert has been changed to the use of the new Tokens contract which can enforce other contracts validation by forwarding eval - > validate call to GatewaysValidate
+ + So all tokens remain within that Tokens contract eval code .
Care must be taken so that tokens are not lost and can be converted back .
This changes the usage to require tokenconvert before doing the bind and also tokenconvert before doing a withdraw . EVAL_GATEWAYS has evalcode of 241
The gatewaysclaim automatically converts the deposit amount of tokens back to EVAL_ASSETS .
- - Care must be taken so that tokens are not lost and can be converted back .
- - This changes the usage to require tokenconvert before doing the bind and also tokenconvert before doing a withdraw . EVAL_GATEWAYS has evalcode of 241
+ + tokenconvert now returns ' not implemented ' , no need to use it at all .
- - The gatewaysclaim automatically converts the deposit amount of tokens back to EVAL_ASSETS .
+ + The gatewaysclaim automatically transfers the deposit amount of tokens to depositor ' s address ( within EVAL_TOKENS ) .
*/
@ -204,38 +208,42 @@ uint8_t DecodeGatewaysDepositOpRet(const CScript &scriptPubKey,std::string &coin
return ( 0 ) ;
}
CScript EncodeGatewaysClaimOpRet ( uint8_t funcid , uint256 assetid , std : : string refcoin , uint256 bindtxid , uint256 deposittxid , CPubKey destpub , int64_t amount )
// encodes payload for the token opret (needs to be added to the tail of it)
CScript EncodeGatewaysClaimOpRet ( uint8_t funcid , std : : string refcoin , uint256 bindtxid , uint256 deposittxid , CPubKey destpub , int64_t amount )
{
CScript opret ; uint8_t evalcode = EVAL_ASSETS ;
opret < < OP_RETURN < < E_MARSHAL ( ss < < evalcode < < funcid < < assetid < < refcoin < < bindtxid < < deposittxid < < destpub < < amount ) ;
CScript opret ;
opret < < OP_RETURN < < E_MARSHAL ( ss < < funcid < < refcoin < < bindtxid < < deposittxid < < destpub < < amount ) ;
return ( opret ) ;
}
uint8_t DecodeGatewaysClaimOpRet ( const CScript & scriptPubKey , uint256 & asse tid, std : : string & refcoin , uint256 & bindtxid , uint256 & deposittxid , CPubKey & destpub , int64_t & amount )
uint8_t DecodeGatewaysClaimOpRet ( const CScript & scriptPubKey , uint256 & token id , std : : string & refcoin , uint256 & bindtxid , uint256 & deposittxid , CPubKey & destpub , int64_t & amount )
{
std : : vector < uint8_t > vopret ; uint8_t * script , e , f ;
GetOpReturnData ( scriptPubKey , vopret ) ;
script = ( uint8_t * ) vopret . data ( ) ;
if ( vopret . size ( ) > 2 & & E_UNMARSHAL ( vopret , ss > > e ; ss > > f ; ss > > asse tid; ss > > refcoin ; ss > > bindtxid ; ss > > deposittxid ; ss > > destpub ; ss > > amount ) ! = 0 )
if ( vopret . size ( ) > 2 & & E_UNMARSHAL ( vopret , ss > > e ; ss > > f ; ss > > token id ; ss > > refcoin ; ss > > bindtxid ; ss > > deposittxid ; ss > > destpub ; ss > > amount ) ! = 0 )
{
return ( f ) ;
}
return ( 0 ) ;
}
CScript EncodeGatewaysWithdrawOpRet ( uint8_t funcid , uint256 assetid , std : : string refcoin , CPubKey withdrawpub , int64_t amount )
CScript EncodeGatewaysWithdrawOpRet ( uint8_t funcid , std : : string refcoin , CPubKey withdrawpub , int64_t amount )
{
CScript opret ; uint8_t evalcode = EVAL_GATEWAYS ;
opret < < OP_RETURN < < E_MARSHAL ( ss < < evalcode < < funcid < < asset id < < refcoin < < withdrawpub < < amount ) ;
CScript opret ;
opret < < OP_RETURN < < E_MARSHAL ( ss < < funcid < < refcoin < < withdrawpub < < amount ) ;
return ( opret ) ;
}
uint8_t DecodeGatewaysWithdrawOpRet ( const CScript & scriptPubKey , uint256 & asse tid, std : : string & refcoin , CPubKey & withdrawpub , int64_t & amount )
uint8_t DecodeGatewaysWithdrawOpRet ( const CScript & scriptPubKey , uint256 & token id , std : : string & refcoin , CPubKey & withdrawpub , int64_t & amount )
{
std : : vector < uint8_t > vopret ; uint8_t * script , e , f ;
GetOpReturnData ( scriptPubKey , vopret ) ;
script = ( uint8_t * ) vopret . data ( ) ;
if ( vopret . size ( ) > 2 & & E_UNMARSHAL ( vopret , ss > > e ; ss > > f ; ss > > asse tid; ss > > refcoin ; ss > > withdrawpub ; ss > > amount ) ! = 0 )
if ( vopret . size ( ) > 2 & & E_UNMARSHAL ( vopret , ss > > e ; ss > > f ; ss > > token id ; ss > > refcoin ; ss > > withdrawpub ; ss > > amount ) ! = 0 )
{
return ( f ) ;
}
@ -304,7 +312,7 @@ uint8_t DecodeGatewaysOpRet(const CScript &scriptPubKey)
std : : vector < uint8_t > vopret ; uint8_t * script , e , f ;
GetOpReturnData ( scriptPubKey , vopret ) ;
script = ( uint8_t * ) vopret . data ( ) ;
if ( vopret . size ( ) > 2 & & ( script [ 0 ] = = EVAL_GATEWAYS | | script [ 0 ] = = EVAL_ASSE TS ) & & E_UNMARSHAL ( vopret , ss > > e ; ss > > f ) ! = 0 )
if ( vopret . size ( ) > 2 & & ( script [ 0 ] = = EVAL_GATEWAYS | | script [ 0 ] = = EVAL_TOKEN S ) & & E_UNMARSHAL ( vopret , ss > > e ; ss > > f ) ! = 0 )
{
if ( f = = ' B ' & & f = = ' D ' & & f = = ' t ' & & f = = ' W ' & & f = = ' P ' & & f = = ' M ' )
return ( f ) ;
@ -512,7 +520,7 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &
int32_t numvins , numvouts , preventCCvins , preventCCvouts , i , numblocks , height , claimvout ; bool retval ; uint8_t funcid , hash [ 32 ] , M , N , taddr , prefix , prefix2 ;
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 totalsupply , amount , tmpamount ;
uint256 hashblock , txid , bindtxid , deposittxid , assetid , oracletxid , tokenid , cointxid , tmptxid , tmpxtxid2 , merkleroot , mhash ; CTransaction bindtx , deposittx , oracletx ;
uint256 hashblock , txid , bindtxid , deposittxid , tokenidClaim , oracletxid , tokenidBin d , cointxid , tmptxid , tmpxtxid2 , merkleroot , mhash ; CTransaction bindtx , deposittx , oracletx ;
std : : string refcoin , tmprefcoin , deposithex ; CPubKey destpub , tmpdestpub ;
fprintf ( stderr , " return true without gateways validation \n " ) ;
@ -565,8 +573,8 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &
//vin.2: CC input of marker from gatewaysdeposit tx
//vout.0: CC vout of total tokens from deposit amount to asset eval code
//(vout.1): CC vout if there is change of unused tokens back to owner of tokens (deposit amount less than available tokens)
//vout.n-1: opreturn - 't' asse tid zeroid 0 mypubkey (NOTE: opreturn is with asset eval code)
if ( ( numvouts = tx . vout . size ( ) ) > 0 & & DecodeGatewaysClaimOpRet ( tx . vout [ numvouts - 1 ] . scriptPubKey , assetid , refcoin , bindtxid , deposittxid , destpub , amount ) = = 0 )
//vout.n-1: opreturn - 't' token id zeroid 0 mypubkey (NOTE: opreturn is with asset eval code)
if ( ( numvouts = tx . vout . size ( ) ) > 0 & & DecodeGatewaysClaimOpRet ( tx . vout [ numvouts - 1 ] . scriptPubKey , tokenidClaim , refcoin , bindtxid , deposittxid , destpub , amount ) = = 0 )
return eval - > Invalid ( " invalid gatewaysclaim OP_RETURN data! " ) ;
else if ( IsCCInput ( tx . vin [ 0 ] . scriptSig ) ! = 0 )
return eval - > Invalid ( " vin.0 is normal for gatewaysClaim! " ) ;
@ -580,12 +588,12 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &
return eval - > Invalid ( " vout.1 is CC for gatewaysClaim! " ) ;
else if ( myGetTransaction ( bindtxid , bindtx , hashblock ) = = 0 )
return eval - > Invalid ( " invalid gatewaysbind txid! " ) ;
else if ( ( numvouts = bindtx . vout . size ( ) ) > 0 & & DecodeGatewaysBindOpRet ( depositaddr , bindtx . vout [ numvouts - 1 ] . scriptPubKey , tmprefcoin , tokenid , totalsupply , oracletxid , M , N , pubkeys , taddr , prefix , prefix2 ) ! = ' B ' )
else if ( ( numvouts = bindtx . vout . size ( ) ) > 0 & & DecodeGatewaysBindOpRet ( depositaddr , bindtx . vout [ numvouts - 1 ] . scriptPubKey , tmprefcoin , tokenidBind , totalsupply , oracletxid , M , N , pubkeys , taddr , prefix , prefix2 ) ! = ' B ' )
return eval - > Invalid ( " invalid gatewaysbind OP_RETURN data! " ) ;
else if ( tmprefcoin ! = refcoin )
return eval - > Invalid ( " refcoin different in bind tx " ) ;
else if ( tokenid ! = asse tid)
return eval - > Invalid ( " asse tid does not match tokenid from gatewaysbind" ) ;
else if ( tokenidClaim ! = token idBin d )
return eval - > Invalid ( " token id does not match tokenid from gatewaysbind " ) ;
else if ( komodo_txnotarizedconfirmed ( bindtxid ) = = false )
return eval - > Invalid ( " gatewaysbind tx is not yet confirmed(notarised)! " ) ;
else if ( myGetTransaction ( deposittxid , deposittx , hashblock ) = = 0 )
@ -642,7 +650,7 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &
//vout.1: normal vout txfee marker to withdraw destination pubkey
//vout.2: CC vout txfee marker to gateways CC address
//vout.n-2: CC vout if there is change of unused tokens back to owner of tokens (withdraw amount less than owner available tokens)
//vout.n-1: opreturn - 'W' asse tid refcoin withdrawpub amount
//vout.n-1: opreturn - 'W' token id refcoin withdrawpub amount
break ;
case ' P ' :
//vin.0: normal input
@ -675,9 +683,9 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &
// helper functions for rpc calls in rpcwallet.cpp
int64_t AddGatewaysInputs ( struct CCcontract_info * cp , CMutableTransaction & mtx , CPubKey pk , uint256 refasse tid , int64_t total , int32_t maxinputs )
int64_t AddGatewaysInputs ( struct CCcontract_info * cp , CMutableTransaction & mtx , CPubKey pk , uint256 reftoken id , int64_t total , int32_t maxinputs )
{
char coinaddr [ 64 ] , destaddr [ 64 ] ; int64_t threshold , nValue , price , totalinputs = 0 ; uint256 asse tid, txid , hashBlock ; std : : vector < uint8_t > origpubkey ; std : : vector < uint8_t > vopret ; CTransaction vintx ; int32_t j , vout , n = 0 ; uint8_t evalcode , funcid ;
char coinaddr [ 64 ] , destaddr [ 64 ] ; int64_t threshold , nValue , price , totalinputs = 0 ; uint256 token id , txid , hashBlock ; std : : vector < uint8_t > origpubkey ; std : : vector < uint8_t > vopret ; CTransaction vintx ; int32_t j , vout , n = 0 ; uint8_t evalcode , funcid ;
std : : vector < std : : pair < CAddressUnspentKey , CAddressUnspentValue > > unspentOutputs ;
GetCCaddress ( cp , coinaddr , pk ) ;
SetCCunspents ( unspentOutputs , coinaddr ) ;
@ -701,11 +709,11 @@ int64_t AddGatewaysInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP
if ( strcmp ( destaddr , coinaddr ) ! = 0 & & strcmp ( destaddr , cp - > unspendableCCaddr ) ! = 0 & & strcmp ( destaddr , cp - > unspendableaddr2 ) ! = 0 )
continue ;
GetOpReturnData ( vintx . vout [ vintx . vout . size ( ) - 1 ] . scriptPubKey , vopret ) ;
if ( E_UNMARSHAL ( vopret , ss > > evalcode ; ss > > funcid ; ss > > asse tid) ! = 0 )
if ( E_UNMARSHAL ( vopret , ss > > evalcode ; ss > > funcid ; ss > > token id ) ! = 0 )
{
asse tid = revuint256 ( asse tid) ;
char str [ 65 ] , str2 [ 65 ] ; fprintf ( stderr , " vout.%d %d:%d (%c) check for refasse tid.%s vs %s %.8f \n " , vout , evalcode , cp - > evalcode , funcid , uint256_str ( str , refasse tid ) , uint256_str ( str2 , asse tid) , ( double ) vintx . vout [ vout ] . nValue / COIN ) ;
if ( asse tid = = refasse tid & & funcid = = ' t ' & & ( nValue = vintx . vout [ vout ] . nValue ) > 0 & & myIsutxo_spentinmempool ( txid , vout ) = = 0 )
token id = revuint256 ( token id ) ;
char str [ 65 ] , str2 [ 65 ] ; fprintf ( stderr , " vout.%d %d:%d (%c) check for reftoken id.%s vs %s %.8f \n " , vout , evalcode , cp - > evalcode , funcid , uint256_str ( str , reftoken id ) , uint256_str ( str2 , token id ) , ( double ) vintx . vout [ vout ] . nValue / COIN ) ;
if ( token id = = reftoken id & & funcid = = ' t ' & & ( nValue = vintx . vout [ vout ] . nValue ) > 0 & & myIsutxo_spentinmempool ( txid , vout ) = = 0 )
{
//fprintf(stderr,"total %llu maxinputs.%d %.8f\n",(long long)total,maxinputs,(double)it->second.satoshis/COIN);
if ( total ! = 0 & & maxinputs ! = 0 )
@ -905,7 +913,7 @@ std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,ui
CTransaction tx ; CPubKey mypk , gatewayspk , tmpdestpub ; struct CCcontract_info * cp , C ; uint8_t M , N , taddr , prefix , prefix2 ;
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 , asse tid, oracletxid , tmptxid , cointxid ; char str [ 65 ] , depositaddr [ 64 ] , coinaddr [ 64 ] , destaddr [ 64 ] ; std : : vector < uint256 > txids ;
uint256 hashBlock , token id , oracletxid , tmptxid , cointxid ; char str [ 65 ] , depositaddr [ 64 ] , coinaddr [ 64 ] , destaddr [ 64 ] ; std : : vector < uint256 > txids ;
cp = CCinit ( & C , EVAL_GATEWAYS ) ;
if ( txfee = = 0 )
@ -917,7 +925,7 @@ std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,ui
fprintf ( stderr , " cant find bindtxid %s \n " , uint256_str ( str , bindtxid ) ) ;
return ( " " ) ;
}
if ( DecodeGatewaysBindOpRet ( depositaddr , tx . vout [ numvouts - 1 ] . scriptPubKey , coin , asse tid, totalsupply , oracletxid , M , N , msigpubkeys , taddr , prefix , prefix2 ) ! = ' B ' | | coin ! = refcoin )
if ( DecodeGatewaysBindOpRet ( depositaddr , tx . vout [ numvouts - 1 ] . scriptPubKey , coin , token id , totalsupply , oracletxid , M , N , msigpubkeys , taddr , prefix , prefix2 ) ! = ' B ' | | coin ! = refcoin )
{
fprintf ( stderr , " invalid coin - bindtxid %s coin.%s \n " , uint256_str ( str , bindtxid ) , coin . c_str ( ) ) ;
return ( " " ) ;
@ -945,17 +953,24 @@ std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,ui
//fprintf(stderr,"depositaddr.(%s) vs %s\n",depositaddr,cp->unspendableaddr2);
if ( AddNormalinputs ( mtx , mypk , txfee , 3 ) > 0 )
{
if ( ( inputs = AddGatewaysInputs ( cp , mtx , gatewayspk , assetid , amount , 60 ) ) > 0 )
///////// if ( (inputs= AddGatewaysInputs(cp,mtx,gatewayspk,tokenid,amount,60)) > 0 )
if ( ( inputs = AddTokenCCInputs ( cp , mtx , gatewayspk , tokenid , amount , 60 ) ) > 0 )
{
if ( inputs > amount )
CCchange = ( inputs - amount ) ;
_GetCCaddress ( destaddr , EVAL_GATEWAYS , mypk ) ;
//printf("expecting deposittxid/v0 to be to %s\n",destaddr);
mtx . vin . push_back ( CTxIn ( deposittxid , 0 , CScript ( ) ) ) ; // triggers EVAL_GATEWAYS validation
mtx . vout . push_back ( MakeCC1vout ( EVAL_ASSE TS , amount , mypk ) ) ; // transfer back to normal token
mtx . vout . push_back ( MakeCC1vout ( EVAL_TOKEN S , amount , mypk ) ) ; // transfer back to normal token
if ( CCchange ! = 0 )
mtx . vout . push_back ( MakeCC1vout ( EVAL_GATEWAYS , CCchange , gatewayspk ) ) ;
return ( FinalizeCCTx ( 0 , cp , mtx , mypk , txfee , EncodeGatewaysClaimOpRet ( ' t ' , assetid , refcoin , bindtxid , deposittxid , destpub , amount ) ) ) ;
mtx . vout . push_back ( MakeCC1vout ( EVAL_GATEWAYS , CCchange , gatewayspk ) ) ;
std : : vector < CPubKey > voutTokenPubkeys ;
voutTokenPubkeys . push_back ( mypk ) ; // the pubkey where tokens are going (vout[0])
return ( FinalizeCCTx ( 0 , cp , mtx , mypk , txfee ,
EncodeTokenOpRet ( ' t ' , EVAL_GATEWAYS , tokenid , voutTokenPubkeys ,
EncodeGatewaysClaimOpRet ( ' t ' , refcoin , bindtxid , deposittxid , destpub , amount ) ) ) ) ; // yes, 't' is passed twice
}
}
CCerror = strprintf ( " cant find enough inputs or mismatched total " ) ;
@ -966,39 +981,67 @@ std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,ui
std : : string GatewaysWithdraw ( uint64_t txfee , uint256 bindtxid , std : : string refcoin , CPubKey withdrawpub , int64_t amount )
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction ( Params ( ) . GetConsensus ( ) , komodo_nextheight ( ) ) ;
CTransaction tx ; CPubKey mypk , gatewayspk ; struct CCcontract_info * cp , C ;
uint256 assetid , hashBlock , oracletxid ; int32_t numvouts ; int64_t totalsupply , inputs , CCchange = 0 ; uint8_t M , N , taddr , prefix , prefix2 ; std : : string coin ;
CTransaction tx ;
CPubKey mypk , gatewayspk ;
uint256 tokenid , hashBlock , oracletxid ; int32_t numvouts ; int64_t totalsupply , inputs , CCchange = 0 ; uint8_t M , N , taddr , prefix , prefix2 ; std : : string coin ;
std : : vector < CPubKey > msigpubkeys ; char depositaddr [ 64 ] , str [ 65 ] , coinaddr [ 64 ] ;
cp = CCinit ( & C , EVAL_GATEWAYS ) ;
struct CCcontract_info * cpGateways , gatewaysC ;
struct CCcontract_info * cpTokens , tokensC ;
cpGateways = CCinit ( & gatewaysC , EVAL_GATEWAYS ) ;
cpTokens = CCinit ( & tokensC , EVAL_TOKENS ) ;
if ( txfee = = 0 )
txfee = 10000 ;
mypk = pubkey2pk ( Mypubkey ( ) ) ;
gatewayspk = GetUnspendable ( cp , 0 ) ;
if ( GetTransaction ( bindtxid , tx , hashBlock , false ) = = 0 | | ( numvouts = tx . vout . size ( ) ) < = 0 )
gatewayspk = GetUnspendable ( cpGateways , 0 ) ;
if ( GetTransaction ( bindtxid , tx , hashBlock , false ) = = 0 | | ( numvouts = tx . vout . size ( ) ) < = 0 )
{
fprintf ( stderr , " cant find bindtxid %s \n " , uint256_str ( str , bindtxid ) ) ;
return ( " " ) ;
}
if ( DecodeGatewaysBindOpRet ( depositaddr , tx . vout [ numvouts - 1 ] . scriptPubKey , coin , asse tid, totalsupply , oracletxid , M , N , msigpubkeys , taddr , prefix , prefix2 ) ! = ' B ' | | coin ! = refcoin )
if ( DecodeGatewaysBindOpRet ( depositaddr , tx . vout [ numvouts - 1 ] . scriptPubKey , coin , token id , totalsupply , oracletxid , M , N , msigpubkeys , taddr , prefix , prefix2 ) ! = ' B ' | | coin ! = refcoin )
{
fprintf ( stderr , " invalid bindtxid %s coin.%s \n " , uint256_str ( str , bindtxid ) , coin . c_str ( ) ) ;
return ( " " ) ;
}
if ( AddNormalinputs ( mtx , mypk , 3 * txfee , 4 ) > 0 )
if ( AddNormalinputs ( mtx , mypk , 3 * txfee , 4 ) > 0 )
{
if ( ( inputs = AddGatewaysInputs ( cp , mtx , mypk , assetid , amount , 60 ) ) > 0 )
/////if ( (inputs= AddGatewaysInputs(cp,mtx,mypk,tokenid,amount,60)) > 0 )
if ( ( inputs = AddTokenCCInputs ( cpTokens , mtx , mypk , tokenid , amount , 60 ) ) > 0 )
{
if ( inputs > amount )
CCchange = ( inputs - amount ) ;
mtx . vout . push_back ( MakeCC1vout ( EVAL_GATEWAYS , amount , gatewayspk ) ) ;
mtx . vout . push_back ( MakeCC1vout ( EVAL_TOKENS , amount , gatewayspk ) ) ;
mtx . vout . push_back ( CTxOut ( txfee , CScript ( ) < < ParseHex ( HexStr ( withdrawpub ) ) < < OP_CHECKSIG ) ) ;
mtx . vout . push_back ( MakeCC1vout ( EVAL_GATEWAYS , txfee , gatewayspk ) ) ;
mtx . vout . push_back ( MakeCC1vout ( EVAL_GATEWAYS , txfee , gatewayspk ) ) ;
if ( CCchange ! = 0 )
mtx . vout . push_back ( MakeCC1vout ( EVAL_GATEWAYS , CCchange , mypk ) ) ;
return ( FinalizeCCTx ( 0 , cp , mtx , mypk , txfee , EncodeGatewaysWithdrawOpRet ( ' W ' , assetid , refcoin , withdrawpub , amount ) ) ) ;
mtx . vout . push_back ( MakeCC1vout ( EVAL_TOKENS , CCchange , mypk ) ) ;
char unspendableGatewaysAddr [ 64 ] ;
GetCCaddress ( cpGateways , unspendableGatewaysAddr , gatewayspk ) ;
uint8_t unspendableGatewaysPrivkey [ 32 ] ;
GetUnspendable ( cpGateways , unspendableGatewaysPrivkey ) ;
// add additional unspendable addr from Gateways:
CCaddr2set ( cpTokens , EVAL_GATEWAYS , gatewayspk , unspendableGatewaysPrivkey , unspendableGatewaysAddr ) ;
std : : vector < CPubKey > voutTokenPubkeys ;
voutTokenPubkeys . push_back ( gatewayspk ) ; // the pubkey where tokens are going vout[0] (and for checking the 'change' the Tokens contract will find pubkeys itself)
return ( FinalizeCCTx ( 0 , cpTokens , mtx , mypk , txfee ,
EncodeTokenOpRet ( ' t ' , EVAL_GATEWAYS , tokenid , voutTokenPubkeys ,
EncodeGatewaysWithdrawOpRet ( ' W ' , refcoin , withdrawpub , amount ) ) ) ) ;
}
CCerror = strprintf ( " cant find enough token inputs or mismatched total " ) ;
fprintf ( stderr , " %s \n " , CCerror . c_str ( ) ) ;
return ( " " ) ;
}
CCerror = strprintf ( " cant find enough inputs or mismatched total " ) ;
CCerror = strprintf ( " cant find enough normal inputs or mismatched total " ) ;
fprintf ( stderr , " %s \n " , CCerror . c_str ( ) ) ;
return ( " " ) ;
}
@ -1073,7 +1116,7 @@ std::string GatewaysMarkDone(uint64_t txfee,uint256 completetxid,std::string ref
UniValue GatewaysPendingWithdraws ( uint256 bindtxid , std : : string refcoin )
{
UniValue result ( UniValue : : VOBJ ) , pending ( UniValue : : VARR ) ; CTransaction tx ; std : : string tmprefcoin ; CPubKey mypk , gatewayspk , withdrawpub ; std : : vector < CPubKey > msigpubkeys ;
uint256 hashBlock , asse tid, txid , oracletxid ; uint8_t M , N , taddr , prefix , prefix2 ;
uint256 hashBlock , token id , txid , oracletxid ; uint8_t M , N , taddr , prefix , prefix2 ;
char depositaddr [ 64 ] , coinaddr [ 64 ] , destaddr [ 64 ] , str [ 65 ] , withaddr [ 64 ] , numstr [ 32 ] , txidaddr [ 64 ] , cctxidaddr [ 64 ] , signeraddr [ 64 ] ;
int32_t i , n , numvouts , vout , queueflag ; int64_t totalsupply , amount , nValue ; struct CCcontract_info * cp , C ;
std : : vector < std : : pair < CAddressUnspentKey , CAddressUnspentValue > > unspentOutputs ;
@ -1087,7 +1130,7 @@ UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
fprintf ( stderr , " cant find bindtxid %s \n " , uint256_str ( str , bindtxid ) ) ;
return ( result ) ;
}
if ( DecodeGatewaysBindOpRet ( depositaddr , tx . vout [ numvouts - 1 ] . scriptPubKey , tmprefcoin , asse tid, totalsupply , oracletxid , M , N , msigpubkeys , taddr , prefix , prefix2 ) ! = ' B ' | | tmprefcoin ! = refcoin )
if ( DecodeGatewaysBindOpRet ( depositaddr , tx . vout [ numvouts - 1 ] . scriptPubKey , tmprefcoin , token id , totalsupply , oracletxid , M , N , msigpubkeys , taddr , prefix , prefix2 ) ! = ' B ' | | tmprefcoin ! = refcoin )
{
fprintf ( stderr , " invalid bindtxid %s coin.%s \n " , uint256_str ( str , bindtxid ) , tmprefcoin . c_str ( ) ) ;
return ( result ) ;
@ -1108,7 +1151,7 @@ UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
nValue = ( int64_t ) it - > second . satoshis ;
fprintf ( stderr , " %s %d %ld \n " , txid . ToString ( ) . c_str ( ) , vout , ( long ) nValue ) ;
if ( vout = = 2 & & nValue = = 10000 & & GetTransaction ( txid , tx , hashBlock , false ) ! = 0 & & ( numvouts = tx . vout . size ( ) ) > 0 & &
DecodeGatewaysWithdrawOpRet ( tx . vout [ numvouts - 1 ] . scriptPubKey , asse tid, tmprefcoin , withdrawpub , amount ) = = ' W ' & & myIsutxo_spentinmempool ( txid , vout ) = = 0 )
DecodeGatewaysWithdrawOpRet ( tx . vout [ numvouts - 1 ] . scriptPubKey , token id , tmprefcoin , withdrawpub , amount ) = = ' W ' & & myIsutxo_spentinmempool ( txid , vout ) = = 0 )
{
Getscriptaddress ( destaddr , tx . vout [ 0 ] . scriptPubKey ) ;
Getscriptaddress ( withaddr , tx . vout [ 1 ] . scriptPubKey ) ;
@ -1141,7 +1184,7 @@ UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
UniValue GatewaysProcessedWithdraws ( uint256 bindtxid , std : : string refcoin )
{
UniValue result ( UniValue : : VOBJ ) , processed ( UniValue : : VARR ) ; CTransaction tx ; std : : string tmprefcoin , hex ; CPubKey mypk , gatewayspk , withdrawpub ; std : : vector < CPubKey > msigpubkeys ;
uint256 withdrawtxid , hashBlock , txid , asse tid, oracletxid ; uint8_t M , N , taddr , prefix , prefix2 ;
uint256 withdrawtxid , hashBlock , txid , token id , oracletxid ; uint8_t M , N , taddr , prefix , prefix2 ;
char depositaddr [ 64 ] , coinaddr [ 64 ] , str [ 65 ] , numstr [ 32 ] , txidaddr [ 64 ] , cctxidaddr [ 64 ] , withaddr [ 64 ] ;
int32_t i , n , numvouts , vout , queueflag ; int64_t totalsupply , nValue , amount ; struct CCcontract_info * cp , C ;
std : : vector < std : : pair < CAddressUnspentKey , CAddressUnspentValue > > unspentOutputs ;
@ -1155,7 +1198,7 @@ UniValue GatewaysProcessedWithdraws(uint256 bindtxid,std::string refcoin)
fprintf ( stderr , " cant find bindtxid %s \n " , uint256_str ( str , bindtxid ) ) ;
return ( result ) ;
}
if ( DecodeGatewaysBindOpRet ( depositaddr , tx . vout [ numvouts - 1 ] . scriptPubKey , tmprefcoin , asse tid, totalsupply , oracletxid , M , N , msigpubkeys , taddr , prefix , prefix2 ) ! = ' B ' | | tmprefcoin ! = refcoin )
if ( DecodeGatewaysBindOpRet ( depositaddr , tx . vout [ numvouts - 1 ] . scriptPubKey , tmprefcoin , token id , totalsupply , oracletxid , M , N , msigpubkeys , taddr , prefix , prefix2 ) ! = ' B ' | | tmprefcoin ! = refcoin )
{
fprintf ( stderr , " invalid bindtxid %s coin.%s \n " , uint256_str ( str , bindtxid ) , tmprefcoin . c_str ( ) ) ;
return ( result ) ;
@ -1178,7 +1221,7 @@ UniValue GatewaysProcessedWithdraws(uint256 bindtxid,std::string refcoin)
if ( vout = = 0 & & nValue = = 10000 & & GetTransaction ( txid , tx , hashBlock , false ) ! = 0 & & ( numvouts = tx . vout . size ( ) ) > 0 & &
DecodeGatewaysCompleteSigningOpRet ( tx . vout [ numvouts - 1 ] . scriptPubKey , tmprefcoin , withdrawtxid , hex ) = = ' C ' & & myIsutxo_spentinmempool ( txid , vout ) = = 0 )
{
if ( GetTransaction ( withdrawtxid , tx , hashBlock , false ) ! = 0 & & ( numvouts = tx . vout . size ( ) ) > 0 & & DecodeGatewaysWithdrawOpRet ( tx . vout [ numvouts - 1 ] . scriptPubKey , asse tid, tmprefcoin , withdrawpub , amount ) = = ' W ' )
if ( GetTransaction ( withdrawtxid , tx , hashBlock , false ) ! = 0 & & ( numvouts = tx . vout . size ( ) ) > 0 & & DecodeGatewaysWithdrawOpRet ( tx . vout [ numvouts - 1 ] . scriptPubKey , token id , tmprefcoin , withdrawpub , amount ) = = ' W ' )
{
UniValue obj ( UniValue : : VOBJ ) ;
obj . push_back ( Pair ( " txid " , uint256_str ( str , txid ) ) ) ;