diff --git a/src/cc/CCtokens.cpp b/src/cc/CCtokens.cpp index 0bd4dd991..5c848b081 100644 --- a/src/cc/CCtokens.cpp +++ b/src/cc/CCtokens.cpp @@ -285,7 +285,7 @@ bool ExtractVinPubkeys(struct CCcontract_info *cp, CTransaction tx, std::vector< thread_local uint32_t tokenValIndentSize = 0; // validates opret for token tx: -bool ValidateTokenOpret(CTransaction tx, int32_t v, uint256 tokenid, std::vector &voutPubkeys, std::vector &vopretExtra) { +uint8_t ValidateTokenOpret(CTransaction tx, int32_t v, uint256 tokenid, std::vector &voutPubkeys, std::vector &vopretExtra) { uint256 tokenidOpret, tokenidOpret2; uint8_t funcid; @@ -305,7 +305,7 @@ bool ValidateTokenOpret(CTransaction tx, int32_t v, uint256 tokenid, std::vector { if (tokenid != zeroid && tokenid == tx.GetHash() && v == 0) { //std::cerr << indentStr << "ValidateTokenOpret() this is the tokenbase 'c' tx, txid=" << tx.GetHash().GetHex() << " vout=" << v << " returning true" << std::endl; - return(true); + return funcid; } } else if (funcid == 't') @@ -313,18 +313,18 @@ bool ValidateTokenOpret(CTransaction tx, int32_t v, uint256 tokenid, std::vector //std::cerr << indentStr << "ValidateTokenOpret() tokenid=" << tokenid.GetHex() << " tokenIdOpret=" << tokenidOpret.GetHex() << " txid=" << tx.GetHash().GetHex() << std::endl; if (tokenid != zeroid && tokenid == tokenidOpret) { //std::cerr << indentStr << "ValidateTokenOpret() this is a transfer 't' tx, txid=" << tx.GetHash().GetHex() << " vout=" << v << " returning true" << std::endl; - return(true); + return funcid; } } //std::cerr << indentStr << "ValidateTokenOpret() return false funcid=" << (char)funcid << " tokenid=" << tokenid.GetHex() << " tokenIdOpret=" << tokenidOpret.GetHex() << " txid=" << tx.GetHash().GetHex() << std::endl; - return false; + return (uint8_t)0; } - - // Checks if the vout is a really Tokens CC vout -// compareTotals == true, the func also validates the passed transaction itself: +// also checks tokenid in opret or txid if this is 'c' tx +// goDeeper is true: the func also validates amounts of the passed transaction: // it should be either sum(cc vins) == sum(cc vouts) or the transaction is the 'tokenbase' ('c') tx +// checkPubkeys is true: validates if the vout is token vout1 or token vout1of2. Should always be true! int64_t IsTokensvout(bool goDeeper, bool checkPubkeys, struct CCcontract_info *cp, Eval* eval, std::vector &vopretExtra, const CTransaction& tx, int32_t v, uint256 reftokenid, std::vector vinPubkeys) { @@ -365,12 +365,12 @@ int64_t IsTokensvout(bool goDeeper, bool checkPubkeys, struct CCcontract_info *c // moved opret checking to this new reusable func (dimxy): std::vector voutPubkeys; - const bool valOpret = ValidateTokenOpret(tx, v, reftokenid, voutPubkeys, vopretExtra); + const uint8_t funcId = ValidateTokenOpret(tx, v, reftokenid, voutPubkeys, vopretExtra); //std::cerr << indentStr << "IsTokensvout() ValidateTokenOpret returned=" << std::boolalpha << valOpret << " for txid=" << tx.GetHash().GetHex() << " for tokenid=" << reftokenid.GetHex() << std::endl; - if (valOpret) { + if (funcId != 0) { //std::cerr << indentStr << "IsTokensvout() ValidateTokenOpret returned true" << " for txid=" << tx.GetHash().GetHex() << " for tokenid=" << reftokenid.GetHex() << std::endl; - if (checkPubkeys) { // verify that the vout is within EVAL_TOKENS: + if (checkPubkeys && funcId != 'c') { // verify that the vout is token's (for 'c' there is no pubkeys!): CScript contractScript = CScript(vopretExtra); std::vector vcontractOpret; @@ -605,7 +605,7 @@ std::string TokenTransfer(int64_t txfee, uint256 assetid, std::vector d if (inputs > total) CCchange = (inputs - total); //for (i=0; i pks; pks.push_back(CCNewSecp256k1(pk1)); pks.push_back(CCNewSecp256k1(pk2)); - CC *condEvalCC = CCNewEval(E_MARSHAL(ss << evalcode)); // this is eval cc - CC *condEvalTokensCC = CCNewEval(E_MARSHAL(ss << (uint8_t)EVAL_TOKENS)); // this is eval token cc - CC *cond1of2Sig = CCNewThreshold(1, pks); // this is 1 of 2 sigs cc - CC *cond1of2Threshold = CCNewThreshold(3, { condEvalCC, condEvalTokensCC, cond1of2Sig }); - return cond1of2Threshold; + std::vector thresholds; + thresholds.push_back( CCNewEval(E_MARSHAL(ss << evalcode)) ); + if( evalcode != EVAL_TOKENS ) // if evalCode == EVAL_TOKENS, it is actually MakeCCcond1of2()! + thresholds.push_back(CCNewEval(E_MARSHAL(ss << (uint8_t)EVAL_TOKENS))); // this is eval token cc + thresholds.push_back(CCNewThreshold(1, pks)); // this is 1 of 2 sigs cc + + return CCNewThreshold(thresholds.size(), thresholds); } CC *MakeTokensCCcond1(uint8_t evalcode, CPubKey pk) { std::vector pks; pks.push_back(CCNewSecp256k1(pk)); - CC *condEvalCC = CCNewEval(E_MARSHAL(ss << evalcode)); // add eval cc - CC *condEvalTokensCC = CCNewEval(E_MARSHAL(ss << (uint8_t)EVAL_TOKENS)); // add also eval token cc - CC *Sig = CCNewThreshold(1, pks); - return CCNewThreshold(3, { condEvalCC, condEvalTokensCC, Sig }); + + std::vector thresholds; + thresholds.push_back(CCNewEval(E_MARSHAL(ss << evalcode))); + if (evalcode != EVAL_TOKENS) // if evalCode == EVAL_TOKENS, it is actually MakeCCcond1()! + thresholds.push_back(CCNewEval(E_MARSHAL(ss << (uint8_t)EVAL_TOKENS))); // this is eval token cc + thresholds.push_back(CCNewThreshold(1, pks)); // signature + + return CCNewThreshold(thresholds.size(), thresholds); } CTxOut MakeTokensCC1of2vout(uint8_t evalcode, CAmount nValue, CPubKey pk1, CPubKey pk2)