corr call to DecodeTokenOpRet

This commit is contained in:
dimxy
2019-02-11 20:04:50 +05:00
parent e583658d14
commit 08be0457e6
2 changed files with 32 additions and 10 deletions

View File

@@ -125,7 +125,7 @@ uint8_t DecodeTokenCreateOpRet(const CScript &scriptPubKey,std::vector<uint8_t>
// we suppose in 'c' opret it might be only non-fungible payload and not any assets/heir/etc payloads
if (!ss.eof()) { \
ss >> fieldId; \
if( fieldId == OPRETID_NONFUNGIBLEDATA) \
if( fieldId == OPRETID_NONFUNGIBLEDATA ) \
ss >> vopretNonfungible; \
}))
return(funcid);
@@ -153,6 +153,9 @@ uint8_t DecodeTokenCreateOpRet(const CScript &scriptPubKey,std::vector<uint8_t>
return funcId;
} */
// decodes token opret:
// for 't' returns all data from opret, vopretExtra contains other contract's data (currently only assets').
// for 'c' returns only funcid. NOTE: nonfungible data is not returned
uint8_t DecodeTokenOpRet(const CScript scriptPubKey, uint8_t &evalCodeTokens, uint256 &tokenid, std::vector<CPubKey> &voutPubkeys, std::vector<uint8_t> &vopretExtra)
{
std::vector<uint8_t> vopret, extra, dummyPubkey, vnonfungibleDummy;
@@ -163,6 +166,7 @@ uint8_t DecodeTokenOpRet(const CScript scriptPubKey, uint8_t &evalCodeTokens, ui
GetOpReturnData(scriptPubKey, vopret);
script = (uint8_t *)vopret.data();
tokenid = zeroid;
vopretExtra.clear();
if (script != NULL && vopret.size() > 2)
{
@@ -174,7 +178,7 @@ uint8_t DecodeTokenOpRet(const CScript scriptPubKey, uint8_t &evalCodeTokens, ui
return (uint8_t)0;
funcId = script[1];
LOGSTREAM((char *)"cctokens", CCLOG_DEBUG1, stream << "DecodeTokenOpRet decoded funcId=" << (char)(funcId?funcId:' '));
LOGSTREAM((char *)"cctokens", CCLOG_DEBUG2, stream << "DecodeTokenOpRet decoded funcId=" << (char)(funcId?funcId:' '));
switch( funcId )
{
@@ -407,6 +411,20 @@ uint8_t ValidateTokenOpret(CTransaction tx, uint256 tokenid) {
return (uint8_t)0;
}
// remove token->unspendablePk (it is only for marker usage)
std::vector<CPubKey> FilterOutTokensUnspendablePk(std::vector<CPubKey> sourcePubkeys) {
struct CCcontract_info *cpTokens, tokensC;
cpTokens = CCinit(&tokensC, EVAL_TOKENS);
CPubKey tokensUnspendablePk = GetUnspendable(cpTokens, NULL);
std::vector<CPubKey> destPubkeys;
for (auto pk : sourcePubkeys)
if (pk != tokensUnspendablePk)
destPubkeys.push_back(pk);
return destPubkeys;
}
// Checks if the vout is a really Tokens CC vout
// also checks tokenid in opret or txid if this is 'c' tx
// goDeeper is true: the func also validates amounts of the passed transaction:
@@ -457,7 +475,7 @@ int64_t IsTokensvout(bool goDeeper, bool checkPubkeys /*<--not used, always true
uint8_t dummyEvalCode;
uint256 tokenIdOpret;
std::vector<CPubKey> voutPubkeys;
std::vector<CPubKey> voutPubkeys, voutPubkeysInOpret;
std::vector<uint8_t> vopretExtra, vopretNonfungible;
uint8_t evalCode = EVAL_TOKENS; // if both payloads are empty maybe it is a transfer to non-payload-one-eval-token vout like GatewaysClaim
@@ -466,11 +484,13 @@ int64_t IsTokensvout(bool goDeeper, bool checkPubkeys /*<--not used, always true
// test vouts for possible token use-cases:
std::vector<std::pair<CTxOut, std::string>> testVouts;
DecodeTokenOpRet(tx.vout.back().scriptPubKey, dummyEvalCode, tokenIdOpret, voutPubkeys, vopretExtra);
DecodeTokenOpRet(tx.vout.back().scriptPubKey, dummyEvalCode, tokenIdOpret, voutPubkeysInOpret, vopretExtra);
LOGSTREAM((char *)"cctokens", CCLOG_DEBUG2, stream << "IsTokensvout() vopretExtra=" << HexStr(vopretExtra) << std::endl);
GetNonfungibleData(reftokenid, vopretNonfungible);
voutPubkeys = FilterOutTokensUnspendablePk(voutPubkeysInOpret);
// NOTE: evalcode order in vouts is important:
// non-fungible-eval -> EVAL_TOKENS -> assets-eval
@@ -529,8 +549,10 @@ int64_t IsTokensvout(bool goDeeper, bool checkPubkeys /*<--not used, always true
}
// maybe it is single-eval or dual/three-eval token change?
std::vector<CPubKey> vinPubkeys;
ExtractTokensVinPubkeys(tx, vinPubkeys);
std::vector<CPubKey> vinPubkeys, vinPubkeysUnfiltered;
ExtractTokensVinPubkeys(tx, vinPubkeysUnfiltered);
vinPubkeys = FilterOutTokensUnspendablePk(vinPubkeysUnfiltered);
for(std::vector<CPubKey>::iterator it = vinPubkeys.begin(); it != vinPubkeys.end(); it++) {
testVouts.push_back(std::make_pair(MakeCC1vout(EVAL_TOKENS, tx.vout[v].nValue, *it), std::string("single-eval cc1 self vin pk")));
testVouts.push_back(std::make_pair(MakeTokensCC1vout(evalCode, evalCode2, tx.vout[v].nValue, *it), std::string("three-eval cc1 self vin pk")));
@@ -805,7 +827,7 @@ std::string CreateToken(int64_t txfee, int64_t tokensupply, std::string name, st
mtx.vout.push_back(MakeTokensCC1vout(destEvalCode, tokensupply, mypk));
//mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(cp->CChexstr) << OP_CHECKSIG)); // old marker (non-burnable because spending could not be validated)
// NOTE: we should prevent spending fake-tokens from this marker in IsTokenvout():
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, txfee, GetUnspendable(cp, NULL))); // new marker to cc addr, burnable and validated
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, txfee, GetUnspendable(cp, NULL))); // new marker to token cc addr, burnable and validated
return(FinalizeCCTx(0, cp, mtx, mypk, txfee, EncodeTokenCreateOpRet('c', Mypubkey(), name, description, nonfungibleData)));
}

View File

@@ -218,7 +218,7 @@ uint8_t rogue_registeropretdecode(uint256 &gametxid,uint256 &tokenid,uint256 &pl
{
return(f);
}
else if ( (f= DecodeTokenOpRet(scriptPubKey,e,tokenid,voutPubkeys,vopret,vopret2)) == 'c' || f == 't' )
else if ( (f= DecodeTokenOpRet(scriptPubKey,e,tokenid,voutPubkeys,vopret)) == 'c' || f == 't' )
{
//fprintf(stderr,"got valid token opret %s e.%d vs %d\n",tokenid.GetHex().c_str(),e,EVAL_TOKENS);
if ( vopret2.size() > 2 && E_UNMARSHAL(vopret2,ss >> e; ss >> f; ss >> gametxid; ss >> playertxid) != 0 && e == EVAL_ROGUE && f == 'R' )
@@ -731,7 +731,7 @@ UniValue rogue_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
if ( funcid == 'c' )
tokenid = playertxid;
rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee,
EncodeTokenOpRet(tokenid, voutPubkeysEmpty /*=never spent*/, opretRegister));
EncodeTokenOpRet(tokenid, voutPubkeysEmpty /*=never spent*/, opretRegister));
}
}
}
@@ -881,7 +881,7 @@ UniValue rogue_finishgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
}
}
}
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange + (batonvalue-2*txfee),roguepk));
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange + (batonvalue-3*txfee),roguepk));
cpTokens = CCinit(&tokensC, EVAL_TOKENS);
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, txfee, GetUnspendable(cpTokens, NULL))); // marker to token cc addr, burnable and validated