corrected -> no token vout pubkey validation for 'c'

modified MakeTokenCCcond1 and 1of2 to eliminate duplicate evals
This commit is contained in:
dimxy
2019-01-12 01:06:24 +05:00
parent c4c58b484a
commit 6065a6dec4
2 changed files with 26 additions and 20 deletions

View File

@@ -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<CPubKey> &voutPubkeys, std::vector<uint8_t> &vopretExtra) {
uint8_t ValidateTokenOpret(CTransaction tx, int32_t v, uint256 tokenid, std::vector<CPubKey> &voutPubkeys, std::vector<uint8_t> &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<uint8_t> &vopretExtra, const CTransaction& tx, int32_t v, uint256 reftokenid, std::vector<CPubKey> 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<CPubKey> 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<uint8_t> vcontractOpret;
@@ -605,7 +605,7 @@ std::string TokenTransfer(int64_t txfee, uint256 assetid, std::vector<uint8_t> d
if (inputs > total)
CCchange = (inputs - total);
//for (i=0; i<n; i++)
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, total, pubkey2pk(destpubkey)));
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, total, pubkey2pk(destpubkey))); // TODO: or MakeTokensCC1vout??
if (CCchange != 0)
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, CCchange, mypk));

View File

@@ -82,22 +82,28 @@ CC *MakeTokensCCcond1of2(uint8_t evalcode, CPubKey pk1, CPubKey pk2)
std::vector<CC*> 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<CC*> 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<CC*> 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<CC*> 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)