Browse Source

added more variants checking vouts in IsTokenVout

corr vouts1 in Heir.cpp to single-eval token
changed result type for HeirFund
pull/4/head
dimxy 6 years ago
parent
commit
ec954480a8
  1. 4
      src/cc/CCHeir.h
  2. 1
      src/cc/CCinclude.h
  3. 66
      src/cc/CCtokens.cpp
  4. 55
      src/cc/heir.cpp
  5. 24
      src/cc/heir_validate.h
  6. 12
      src/wallet/rpcwallet.cpp

4
src/cc/CCHeir.h

@ -34,8 +34,8 @@ class TokenHelper;
//template <class Helper> UniValue HeirAdd(uint256 fundingtxid, uint64_t txfee, int64_t amount);
//template <class Helper> UniValue HeirClaim(uint256 fundingtxid, uint64_t txfee, int64_t nValue);
std::string HeirFundCoinCaller(uint64_t txfee, int64_t funds, std::string heirName, CPubKey heirPubkey, int64_t inactivityTimeSec, uint256 assetid);
std::string HeirFundTokenCaller(uint64_t txfee, int64_t funds, std::string heirName, CPubKey heirPubkey, int64_t inactivityTimeSec, uint256 assetid);
UniValue HeirFundCoinCaller(uint64_t txfee, int64_t funds, std::string heirName, CPubKey heirPubkey, int64_t inactivityTimeSec, uint256 assetid);
UniValue HeirFundTokenCaller(uint64_t txfee, int64_t funds, std::string heirName, CPubKey heirPubkey, int64_t inactivityTimeSec, uint256 assetid);
UniValue HeirClaimCoinCaller(uint256 fundingtxid, uint64_t txfee, int64_t amount);
UniValue HeirClaimTokenCaller(uint256 fundingtxid, uint64_t txfee, int64_t amount);
UniValue HeirAddCoinCaller(uint256 fundingtxid, uint64_t txfee, int64_t amount);

1
src/cc/CCinclude.h

@ -162,6 +162,7 @@ CScript EncodeAssetOpRet(uint8_t assetFuncId, uint256 tokenid, uint256 assetid2,
bool DecodeAssetCreateOpRet(const CScript &scriptPubKey, std::vector<uint8_t> &origpubkey, std::string &name, std::string &description);
uint8_t DecodeAssetOpRet(const CScript &scriptPubKey, uint8_t &evalCodeInOpret, uint256 &tokenid, uint256 &assetid2, int64_t &price, std::vector<uint8_t> &origpubkey);
CScript EncodeTokenOpRet(uint256 tokenid, std::vector<CPubKey> voutPubkeys, CScript payload);
CScript EncodeTokenOpRet(uint8_t tokenFuncId, uint8_t evalCodeInOpret, uint256 tokenid, std::vector<CPubKey> voutPubkeys, CScript payload);
uint8_t DecodeTokenCreateOpRet(const CScript &scriptPubKey, std::vector<uint8_t> &origpubkey, std::string &name, std::string &description);
uint8_t DecodeTokenOpRet(const CScript scriptPubKey, uint8_t &evalCode, uint256 &tokenid, std::vector<CPubKey> &voutPubkeys, std::vector<uint8_t> &vopretExtra);

66
src/cc/CCtokens.cpp

@ -51,14 +51,11 @@ CScript EncodeTokenCreateOpRet(uint8_t funcid,std::vector<uint8_t> origpubkey,st
}
// this is for other contracts which use tokens and build customized extra payloads to token's opret:
CScript EncodeTokenOpRet(uint8_t tokenFuncId, uint8_t evalCodeInOpret, uint256 tokenid, std::vector<CPubKey> voutPubkeys, CScript payload)
CScript EncodeTokenOpRet(uint256 tokenid, std::vector<CPubKey> voutPubkeys, CScript payload)
{
CScript opret;
if (evalCodeInOpret != EVAL_TOKENS) {
std::cerr << "EncodeTokenOpRet() evalCode should be EVAL_TOKENS!" << std::endl;
return opret; // return empty
}
uint8_t tokenFuncId = 't';
uint8_t evalCodeInOpret = EVAL_TOKENS;
tokenid = revuint256(tokenid);
@ -93,6 +90,11 @@ CScript EncodeTokenOpRet(uint8_t tokenFuncId, uint8_t evalCodeInOpret, uint256 t
return opret;
}
// overload for compatibility
CScript EncodeTokenOpRet(uint8_t tokenFuncId, uint8_t evalCodeInOpret, uint256 tokenid, std::vector<CPubKey> voutPubkeys, CScript payload)
{
return EncodeTokenOpRet(tokenid, voutPubkeys, payload);
}
uint8_t DecodeTokenCreateOpRet(const CScript &scriptPubKey,std::vector<uint8_t> &origpubkey,std::string &name,std::string &description)
{
@ -405,35 +407,59 @@ int64_t IsTokensvout(bool goDeeper, bool checkPubkeys, struct CCcontract_info *c
std::cerr << "IsTokensvout() vopretExtra=" << HexStr(vopretExtra) << std::endl;
//std::cerr << "IsTokensvout() vcontractOpret=" << HexStr(vcontractOpret) << std::endl;;
if (vopretExtra.size() < 2 /*|| vopretExtra.size() != vopretExtra.begin()[0]*/) {
uint8_t evalCodeInOpret;
if (vopretExtra.size() >= 2 /*|| vopretExtra.size() != vopretExtra.begin()[0] <-- shold we check this?*/) {
std::cerr << "IsTokensvout() empty or incorrect contract opret" << std::endl;
return 0;
evalCodeInOpret = vopretExtra.begin()[1];
}
else {
// if payload is empty maybe it is a claim to non-payload-one-token-eval vout?
evalCodeInOpret = EVAL_TOKENS;
}
uint8_t evalCodeInOpret = vopretExtra.begin()[1];
if (voutPubkeys.size() >= 1 && voutPubkeys.size() <= 2) {
CTxOut testVout;
// maybe this is dual-eval 1 pubkey or 1of2 pubkey vout?
if (voutPubkeys.size() >= 1 && voutPubkeys.size() <= 2) {
CTxOut testDualVout;
if (voutPubkeys.size() == 1)
testVout = MakeTokensCC1vout(evalCodeInOpret, tx.vout[v].nValue, voutPubkeys[0]);
testDualVout = MakeTokensCC1vout(evalCodeInOpret, tx.vout[v].nValue, voutPubkeys[0]);
else // voutPubkeys.size() == 2
testVout = MakeTokensCC1of2vout(evalCodeInOpret, tx.vout[v].nValue, voutPubkeys[0], voutPubkeys[1]);
testDualVout = MakeTokensCC1of2vout(evalCodeInOpret, tx.vout[v].nValue, voutPubkeys[0], voutPubkeys[1]);
if (tx.vout[v].scriptPubKey == testVout.scriptPubKey) {
std::cerr << indentStr << "IsTokensvout() vout is EVAL_TOKENS, returning nValue=" << tx.vout[v].nValue << " for txid=" << tx.GetHash().GetHex() << " for tokenid=" << reftokenid.GetHex() << std::endl;
if (tx.vout[v].scriptPubKey == testDualVout.scriptPubKey) {
if(voutPubkeys.size() == 1)
std::cerr << indentStr << "IsTokensvout() this is dual-eval token vout, eval2=" << evalCodeInOpret << ", returning nValue=" << tx.vout[v].nValue << " for txid=" << tx.GetHash().GetHex() << " for tokenid=" << reftokenid.GetHex() << std::endl;
else
std::cerr << indentStr << "IsTokensvout() this is dual-eval token 1of2 vout or change, eval2=" << evalCodeInOpret << ", returning nValue=" << tx.vout[v].nValue << " for txid=" << tx.GetHash().GetHex() << " for tokenid=" << reftokenid.GetHex() << std::endl;
return tx.vout[v].nValue;
}
}
// maybe it is token change?
// maybe this is claim to single-eval token?
if (voutPubkeys.size() == 1) {
CTxOut testTokenVout1;
testTokenVout1 = MakeCC1vout(EVAL_TOKENS, tx.vout[v].nValue, voutPubkeys[0]);
if (tx.vout[v].scriptPubKey == testTokenVout1.scriptPubKey) {
std::cerr << indentStr << "IsTokensvout() this is single-eval token vout, returning nValue=" << tx.vout[v].nValue << " for txid=" << tx.GetHash().GetHex() << " for tokenid=" << reftokenid.GetHex() << std::endl;
return tx.vout[v].nValue;
}
}
// maybe it is single-eval or dual-eval token change?
std::vector<CPubKey> vinPubkeys;
ExtractTokensVinPubkeys(tx, vinPubkeys);
for(std::vector<CPubKey>::iterator it = vinPubkeys.begin(); it != vinPubkeys.end(); it++) {
CTxOut testVout = MakeTokensCC1vout(evalCodeInOpret, tx.vout[v].nValue, *it);
CTxOut testTokenVout1 = MakeCC1vout(EVAL_TOKENS, tx.vout[v].nValue, *it);
CTxOut testDualVout1 = MakeTokensCC1vout(evalCodeInOpret, tx.vout[v].nValue, *it);
if (tx.vout[v].scriptPubKey == testTokenVout1.scriptPubKey) {
std::cerr << indentStr << "IsTokensvout() this is single-eval token change, returning nValue=" << tx.vout[v].nValue << " for txid=" << tx.GetHash().GetHex() << " for tokenid=" << reftokenid.GetHex() << std::endl;
return tx.vout[v].nValue;
}
if (tx.vout[v].scriptPubKey == testVout.scriptPubKey) {
std::cerr << indentStr << "IsTokensvout() vout is EVAL_TOKENS change, returning nValue=" << tx.vout[v].nValue << " for txid=" << tx.GetHash().GetHex() << " for tokenid=" << reftokenid.GetHex() << std::endl;
if (tx.vout[v].scriptPubKey == testDualVout1.scriptPubKey) {
std::cerr << indentStr << "IsTokensvout() this is dual-eval token change, vout eval2=" << (int)evalCodeInOpret << ", returning nValue=" << tx.vout[v].nValue << " for txid=" << tx.GetHash().GetHex() << " for tokenid=" << reftokenid.GetHex() << std::endl;
return tx.vout[v].nValue;
}
}

55
src/cc/heir.cpp

@ -619,8 +619,9 @@ template <class Helper> int64_t LifetimeHeirContractFunds(struct CCcontract_info
* and also for setting spending plan for the funds' owner and heir
* @return fundingtxid handle for subsequent references to this heir funding plan
*/
template <typename Helper> std::string HeirFund(uint64_t txfee, int64_t amount, std::string heirName, CPubKey heirPubkey, int64_t inactivityTimeSec, uint256 tokenid)
template <typename Helper> UniValue HeirFund(uint64_t txfee, int64_t amount, std::string heirName, CPubKey heirPubkey, int64_t inactivityTimeSec, uint256 tokenid)
{
UniValue result(UniValue::VOBJ);
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
struct CCcontract_info *cp, C;
@ -664,24 +665,38 @@ template <typename Helper> std::string HeirFund(uint64_t txfee, int64_t amount,
voutTokenPubkeys.push_back(heirPubkey);
// add change for txfee and opreturn vouts and sign tx:
return (FinalizeCCTx(0, cp, mtx, myPubkey, txfee,
Helper::makeCreateOpRet(tokenid, voutTokenPubkeys, myPubkey, heirPubkey, inactivityTimeSec, heirName)));
std::string rawhextx = FinalizeCCTx(0, cp, mtx, myPubkey, txfee,
Helper::makeCreateOpRet(tokenid, voutTokenPubkeys, myPubkey, heirPubkey, inactivityTimeSec, heirName));
if (!rawhextx.empty()) {
result.push_back(Pair("result", "success"));
result.push_back(Pair("hextx", rawhextx));
}
else {
std::cerr << "HeirAdd error in FinalizeCCtx" << std::endl;
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "sign error"));
}
}
else { // TODO: need result return unification with heiradd and claim
std::cerr << "HeirFund() could not find owner cc inputs" << std::endl;
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "could not find owner cc inputs"));
}
else // TODO: need result return unification with heiradd and claim
std::cerr << "HeirFund() could not find owner inputs" << std::endl;
}
else
else {
std::cerr << "HeirFund() could not find normal inputs" << std::endl;
return std::string("");
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "could not find normal inputs"));
}
return result;
}
// if no these callers - it could not link
std::string HeirFundCoinCaller(uint64_t txfee, int64_t funds, std::string heirName, CPubKey heirPubkey, int64_t inactivityTimeSec, uint256 tokenid){
UniValue HeirFundCoinCaller(uint64_t txfee, int64_t funds, std::string heirName, CPubKey heirPubkey, int64_t inactivityTimeSec, uint256 tokenid){
return HeirFund<CoinHelper>(txfee, funds, heirName, heirPubkey, inactivityTimeSec, tokenid);
}
std::string HeirFundTokenCaller(uint64_t txfee, int64_t funds, std::string heirName, CPubKey heirPubkey, int64_t inactivityTimeSec, uint256 tokenid) {
UniValue HeirFundTokenCaller(uint64_t txfee, int64_t funds, std::string heirName, CPubKey heirPubkey, int64_t inactivityTimeSec, uint256 tokenid) {
return HeirFund<TokenHelper>(txfee, funds, heirName, heirPubkey, inactivityTimeSec, tokenid);
}
@ -735,8 +750,8 @@ template <class Helper> UniValue HeirAdd(uint256 fundingtxid, uint64_t txfee, in
mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(markerpubkey)) << OP_CHECKSIG)); // txfee 1, txfee 2 - for miners
std::cerr << "HeirAdd() adding markeraddr=" << markeraddr << '\n'; */
// add cryptocondition to spend this funded amount for either pk
mtx.vout.push_back(Helper::make1of2Vout(amount, ownerPubkey, heirPubkey));
// add cryptocondition to spend this funded amount for either pk
mtx.vout.push_back(Helper::make1of2Vout(amount, ownerPubkey, heirPubkey));
if (inputs > amount)
change = (inputs - amount); // -txfee <-- txfee pays user
@ -756,8 +771,16 @@ template <class Helper> UniValue HeirAdd(uint256 fundingtxid, uint64_t txfee, in
std::string rawhextx = (FinalizeCCTx(0, cp, mtx, myPubkey, txfee,
Helper::makeAddOpRet(tokenid, voutTokenPubkeys, fundingtxid, hasHeirSpendingBegun)));
result.push_back(Pair("result", "success"));
result.push_back(Pair("hextx", rawhextx));
if (!rawhextx.empty()) {
result.push_back(Pair("result", "success"));
result.push_back(Pair("hextx", rawhextx));
}
else {
std::cerr << "HeirAdd error in FinalizeCCtx" << std::endl;
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "sign error"));
}
}
else {
std::cerr << "HeirAdd cannot find owner cc inputs" << std::endl;
@ -772,7 +795,7 @@ template <class Helper> UniValue HeirAdd(uint256 fundingtxid, uint64_t txfee, in
}
} else {
fprintf(stderr, "HeirAdd() can't find any heir CC funding tx's\n");
fprintf(stderr, "HeirAdd can't find any heir CC funding tx's\n");
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "can't find any heir CC funding transactions"));
@ -858,7 +881,7 @@ template <typename Helper>UniValue HeirClaim(uint256 fundingtxid, uint64_t txfee
}*/
// add vout with amount to claiming address
mtx.vout.push_back(Helper::makeClaimerVout(amount, myPubkey)); // vout[0]
mtx.vout.push_back(Helper::makeUserVout(amount, myPubkey)); // vout[0]
// calc and add change vout:
if (inputs > amount)

24
src/cc/heir_validate.h

@ -43,9 +43,9 @@ public:
static CTxOut makeUserVout(int64_t amount, CPubKey myPubkey) {
return CTxOut(amount, CScript() << ParseHex(HexStr(myPubkey)) << OP_CHECKSIG);
}
static CTxOut makeClaimerVout(int64_t amount, CPubKey myPubkey) {
/* static CTxOut makeClaimerVout(int64_t amount, CPubKey myPubkey) {
return CTxOut(amount, CScript() << ParseHex(HexStr(myPubkey)) << OP_CHECKSIG);
}
} */
static bool GetCoinsOrTokensCCaddress1of2(char *coinaddr, CPubKey ownerPubkey, CPubKey heirPubkey) {
struct CCcontract_info *cpHeir, heirC;
cpHeir = CCinit(&heirC, EVAL_HEIR);
@ -64,20 +64,20 @@ public:
static uint8_t getMyEval() { return EVAL_TOKENS; }
static int64_t addOwnerInputs(uint256 tokenid, CMutableTransaction& mtx, CPubKey ownerPubkey, int64_t total, int32_t maxinputs) {
struct CCcontract_info *cpHeir, heirC;
cpHeir = CCinit(&heirC, EVAL_HEIR);
cpHeir = CCinit(&heirC, EVAL_TOKENS);
return AddTokenCCInputs(cpHeir, mtx, ownerPubkey, tokenid, total, maxinputs);
}
static CScript makeCreateOpRet(uint256 tokenid, std::vector<CPubKey> voutTokenPubkeys, CPubKey ownerPubkey, CPubKey heirPubkey, int64_t inactivityTimeSec, std::string heirName) {
return EncodeTokenOpRet((uint8_t)'t', EVAL_TOKENS, tokenid, voutTokenPubkeys,
return EncodeTokenOpRet(tokenid, voutTokenPubkeys,
EncodeHeirCreateOpRet((uint8_t)'F', ownerPubkey, heirPubkey, inactivityTimeSec, heirName));
}
static CScript makeAddOpRet(uint256 tokenid, std::vector<CPubKey> voutTokenPubkeys, uint256 fundingtxid, uint8_t isHeirSpendingBegan) {
return EncodeTokenOpRet((uint8_t)'t', EVAL_TOKENS, tokenid, voutTokenPubkeys,
return EncodeTokenOpRet(tokenid, voutTokenPubkeys,
EncodeHeirOpRet((uint8_t)'A', fundingtxid, isHeirSpendingBegan));
}
static CScript makeClaimOpRet(uint256 tokenid, std::vector<CPubKey> voutTokenPubkeys, uint256 fundingtxid, uint8_t isHeirSpendingBegan) {
return EncodeTokenOpRet((uint8_t)'t', EVAL_TOKENS, tokenid, voutTokenPubkeys,
return EncodeTokenOpRet(tokenid, voutTokenPubkeys,
EncodeHeirOpRet((uint8_t)'C', fundingtxid, isHeirSpendingBegan));
}
@ -85,11 +85,11 @@ public:
return MakeTokensCC1of2vout(EVAL_HEIR, amount, ownerPubkey, heirPubkey);
}
static CTxOut makeUserVout(int64_t amount, CPubKey myPubkey) {
return MakeTokensCC1vout(EVAL_HEIR, amount, myPubkey);
}
static CTxOut makeClaimerVout(int64_t amount, CPubKey myPubkey) {
return MakeTokensCC1vout(EVAL_HEIR, amount, myPubkey);
return MakeCC1vout(EVAL_TOKENS, amount, myPubkey); // yes EVAL_TOKENS
}
/* static CTxOut makeClaimerVout(int64_t amount, CPubKey myPubkey) {
return MakeCC1vout(EVAL_TOKENS, amount, myPubkey); // yes EVAL_TOKENS
} */
static bool GetCoinsOrTokensCCaddress1of2(char *coinaddr, CPubKey ownerPubkey, CPubKey heirPubkey) {
struct CCcontract_info *cpHeir, heirC;
cpHeir = CCinit(&heirC, EVAL_HEIR);
@ -477,7 +477,7 @@ public:
CScript ownerScript;
CScript heirScript;
if (m_checkNormals) {
if (m_checkNormals) { //not used, incorrect check, too strict
ownerScript = CoinHelper::makeUserVout(vout.nValue, ownerPubkey).scriptPubKey;
heirScript = CoinHelper::makeUserVout(vout.nValue, heirPubkey).scriptPubKey;
std::cerr << "CMyPubkeyVoutValidator::validateVout() vout.scriptPubKey=" << vout.scriptPubKey.ToString() << " makeUserVout(coin,owner)=" << CoinHelper::makeUserVout(vout.nValue, ownerPubkey).scriptPubKey.ToString() << " makeUserVout(coin,heir)=" << CoinHelper::makeUserVout(vout.nValue, heirPubkey).scriptPubKey.ToString() << std::endl;
@ -537,7 +537,7 @@ public:
int64_t durationSec = CCduration(numblocks, m_latesttxid);
// recreate scriptPubKey for heir and compare it with that of the vout:
if (vout.scriptPubKey == Helper::makeClaimerVout(vout.nValue, heirPubkey).scriptPubKey) {
if (vout.scriptPubKey == Helper::makeUserVout(vout.nValue, heirPubkey).scriptPubKey) {
// this is the heir is trying to spend
if (!m_isHeirSpendingBegan && durationSec <= inactivityTime) {
message = "heir is not allowed yet to spend funds";

12
src/wallet/rpcwallet.cpp

@ -7454,13 +7454,13 @@ UniValue heirfund(const UniValue& params, bool fHelp)
inactivitytime = atof((char*)params[4].get_str().c_str());
hex = HeirFundCoinCaller(txfee, amount, name, pubkey2pk(pubkey), inactivitytime, zeroid);
if (hex.size() > 0) {
result = HeirFundCoinCaller(txfee, amount, name, pubkey2pk(pubkey), inactivitytime, zeroid);
/* if (hex.size() > 0) {
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", hex));
}
else
ERR_RESULT("couldn't create heir fund");
ERR_RESULT("couldn't create heir fund");*/
return result;
}
@ -7573,13 +7573,13 @@ UniValue heirfundtokens(const UniValue& params, bool fHelp)
assetid = Parseuint256((char*)params[5].get_str().c_str());
hex = HeirFundTokenCaller(txfee, amount, name, pubkey2pk(pubkey), inactivitytime, assetid);
if (hex.size() > 0) {
result = HeirFundTokenCaller(txfee, amount, name, pubkey2pk(pubkey), inactivitytime, assetid);
/* if (hex.size() > 0) {
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", hex));
}
else
ERR_RESULT("couldn't create heir fund");
ERR_RESULT("couldn't create heir fund");*/
return result;

Loading…
Cancel
Save