diff --git a/src/cc/CCassets.h b/src/cc/CCassets.h index 0b4dd5578..343108aa8 100644 --- a/src/cc/CCassets.h +++ b/src/cc/CCassets.h @@ -25,10 +25,8 @@ #include "CCinclude.h" -extern const char *AssetsCCaddr; -extern char AssetsCChexstr[67]; // CCcustom -bool IsAssetsInput(CScript const& scriptSig); +bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); // CCassetsCore //CTxOut MakeAssetsVout(CAmount nValue,CPubKey pk); diff --git a/src/cc/CCcustom.cpp b/src/cc/CCcustom.cpp index a689c117f..1f9d634e0 100644 --- a/src/cc/CCcustom.cpp +++ b/src/cc/CCcustom.cpp @@ -14,22 +14,20 @@ ******************************************************************************/ #include "CCinclude.h" +#include "CCassets.h" +#include "CCfaucet.h" +#include "CCrewards.h" /* CCcustom has most of the functions that need to be extended to create a new CC contract. EVAL_CONTRACT is the naming convention and it should be added to cc/eval.h - bool Eval::Dispatch() in cc/eval.h needs to add the validation function in the switch A CC scriptPubKey can only be spent if it is properly signed and validated. By constraining the vins and vouts, it is possible to implement a variety of functionality. CC vouts have an otherwise non-standard form, but it is properly supported by the enhanced bitcoin protocol code as a "cryptoconditions" output and the same pubkey will create a different address. This allows creation of a special address(es) for each contract type, which has the privkey public. That allows anybody to properly sign and spend it, but with the constraints on what is allowed in the validation code, the contract functionality can be implemented. */ -//CC *MakeAssetCond(CPubKey pk); -//CC *MakeFaucetCond(CPubKey pk); -//CC *MakeRewardsCond(CPubKey pk); - //BTCD Address: RAssetsAtGnvwgK9gVHBbAU4sVTah1hAm5 //BTCD Privkey: UvtvQVgVScXEYm4J3r4nE4nbFuGXSVM5pKec8VWXwgG9dmpWBuDh //BTCD Address: RSavingsEYcivt2DFsxsKeCjqArV6oVtVZ @@ -67,82 +65,33 @@ uint8_t RewardsCCpriv[32] = { 0x9f, 0x0c, 0x57, 0xdc, 0x6f, 0x78, 0xae, 0xb0, 0x #undef FUNCNAME #undef EVALCODE -/*bool IsAssetsInput(CScript const& scriptSig) +struct CCcontract_info *CCinit(struct CCcontract_info *cp,uint8_t evalcode) { - CC *cond; - if (!(cond = GetCryptoCondition(scriptSig))) - return false; - // Recurse the CC tree to find asset condition - auto findEval = [&] (CC *cond, struct CCVisitor _) { - bool r = cc_typeId(cond) == CC_Eval && cond->codeLength == 1 && cond->code[0] == EVAL_ASSETS; - // false for a match, true for continue - return r ? 0 : 1; - }; - CCVisitor visitor = {findEval, (uint8_t*)"", 0, NULL}; - bool out =! cc_visit(cond, visitor); - cc_free(cond); - return out; -} - -bool IsFaucetInput(CScript const& scriptSig) -{ - CC *cond; - if (!(cond = GetCryptoCondition(scriptSig))) - return false; - // Recurse the CC tree to find asset condition - auto findEval = [&] (CC *cond, struct CCVisitor _) { - bool r = cc_typeId(cond) == CC_Eval && cond->codeLength == 1 && cond->code[0] == EVAL_FAUCET; - // false for a match, true for continue - return r ? 0 : 1; - }; - CCVisitor visitor = {findEval, (uint8_t*)"", 0, NULL}; - bool out =! cc_visit(cond, visitor); - cc_free(cond); - return out; -} - -bool IsRewardsInput(CScript const& scriptSig) -{ - CC *cond; - if (!(cond = GetCryptoCondition(scriptSig))) - return false; - // Recurse the CC tree to find asset condition - auto findEval = [&] (CC *cond, struct CCVisitor _) { - bool r = cc_typeId(cond) == CC_Eval && cond->codeLength == 1 && cond->code[0] == EVAL_REWARDS; - // false for a match, true for continue - return r ? 0 : 1; - }; - CCVisitor visitor = {findEval, (uint8_t*)"", 0, NULL}; - bool out =! cc_visit(cond, visitor); - cc_free(cond); - return out; -}*/ - -uint64_t AddFaucetInputs(CMutableTransaction &mtx,CPubKey pk,uint64_t total,int32_t maxinputs); - -CPubKey GetUnspendable(uint8_t evalcode,uint8_t *unspendablepriv) -{ - static CPubKey nullpk; - if ( unspendablepriv != 0 ) - memset(unspendablepriv,0,32); - if ( evalcode == EVAL_ASSETS ) - { - if ( unspendablepriv != 0 ) - memcpy(unspendablepriv,AssetsCCpriv,32); - return(pubkey2pk(ParseHex(AssetsCChexstr))); - } - else if ( evalcode == EVAL_FAUCET ) - { - if ( unspendablepriv != 0 ) - memcpy(unspendablepriv,FaucetCCpriv,32); - return(pubkey2pk(ParseHex(FaucetCChexstr))); - } - else if ( evalcode == EVAL_REWARDS ) - { - if ( unspendablepriv != 0 ) - memcpy(unspendablepriv,RewardsCCpriv,32); - return(pubkey2pk(ParseHex(RewardsCChexstr))); - } - else return(nullpk); + cp->evalcode = evalcode; + switch ( evalcode ) + { + case EVAL_ASSETS: + strcpy(cp->CCaddress,AssetsCCaddr); + strcpy(cp->CChexstr,AssetsCChexstr); + memcpy(cp->CCpriv,AssetsCCpriv,32); + cp->validate = AssetsValidate; + cp->ismyvin = IsAssetsInput; + break; + case EVAL_FAUCET: + strcpy(cp->CCaddress,FaucetCCaddr); + strcpy(cp->CChexstr,FaucetCChexstr); + memcpy(cp->CCpriv,FaucetCCpriv,32); + cp->validate = FaucetValidate; + cp->ismyvin = IsFaucetInput; + break; + case EVAL_REWARDS: + strcpy(cp->CCaddress,RewardsCCaddr); + strcpy(cp->CChexstr,RewardsCChexstr); + memcpy(cp->CCpriv,RewardsCCpriv,32); + cp->validate = RewardsValidate; + cp->ismyvin = IsRewardsInput; + break; + } + return(cp); } diff --git a/src/cc/CCcustom.inc b/src/cc/CCcustom.inc index e88a813ac..a5a88f1eb 100644 --- a/src/cc/CCcustom.inc +++ b/src/cc/CCcustom.inc @@ -15,4 +15,3 @@ bool FUNCNAME(CScript const& scriptSig) cc_free(cond); return out; } - diff --git a/src/cc/CCfaucet.h b/src/cc/CCfaucet.h index 42a097369..b478165b5 100644 --- a/src/cc/CCfaucet.h +++ b/src/cc/CCfaucet.h @@ -21,11 +21,9 @@ #define EVAL_FAUCET 0xe4 -extern const char *FaucetCCaddr; -extern char FaucetCChexstr[67]; +bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); // CCcustom -bool IsFaucetInput(CScript const& scriptSig); std::string FaucetFund(uint64_t txfee,uint64_t funds); std::string FaucetGet(uint64_t txfee); diff --git a/src/cc/CCinclude.h b/src/cc/CCinclude.h index 4d1d1cf2c..e4b4c1b52 100644 --- a/src/cc/CCinclude.h +++ b/src/cc/CCinclude.h @@ -28,6 +28,16 @@ #include #include +struct CCcontract_info +{ + char CCaddress[64],CChexstr[72]; + uint8_t CCpriv[32]; + bool (*validate)(Eval* eval,struct CCcontract_info *cp,const CTransaction &tx); + bool (*ismyvin)(CScript const& scriptSig); + uint8_t evalcode; +}; +struct CCcontract_info *CCinit(struct CCcontract_info *cp,uint8_t evalcode); + #ifdef ENABLE_WALLET extern CWallet* pwalletMain; #endif diff --git a/src/cc/CCrewards.h b/src/cc/CCrewards.h new file mode 100644 index 000000000..fe900c02b --- /dev/null +++ b/src/cc/CCrewards.h @@ -0,0 +1,30 @@ +/****************************************************************************** + * Copyright © 2014-2018 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + + +#ifndef CC_REWARDS_H +#define CC_REWARDS_H + +#include "CCinclude.h" + +#define EVAL_REWARDS 0xe5 + +bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); + +std::string RewardsFund(uint64_t txfee,uint64_t funds,uint64_t APR,uint64_t minseconds,uint64_t maxseconds,uint64_t mindeposit); +std::string RewardsLock(uint64_t txfee,uint64_t amount); +std::string RewardsUnlock(uint64_t txfee); + +#endif diff --git a/src/cc/CCutils.cpp b/src/cc/CCutils.cpp index 010727132..ceccee93e 100644 --- a/src/cc/CCutils.cpp +++ b/src/cc/CCutils.cpp @@ -207,3 +207,31 @@ bool Myprivkey(uint8_t myprivkey[]) return(false); } +CPubKey GetUnspendable(struct CCcontract_info *cp,uint8_t *unspendablepriv) +{ + if ( unspendablepriv != 0 ) + memcpy(unspendablepriv,cp->CCpriv,32); + return(pubkey2pk(ParseHex(cp->CChexstr))); +} + +bool ProcessCC(struct CCcontract_info *cp,Eval* eval, std::vector paramsNull,const CTransaction &ctx, unsigned int nIn) +{ + CTransaction createTx; uint256 txid,assetid,assetid2,hashBlock; uint8_t funcid; int32_t i,n; uint64_t amount; std::vector origpubkey; + txid = ctx.GetHash(); + if ( txid == cp->prevtxid ) + return(true); + if ( paramsNull.size() != 0 ) // Don't expect params + return eval->Invalid("Cannot have params"); + else if ( ctx.vout.size() == 0 ) + return eval->Invalid("no-vouts"); + else if ( (*cp->validate)(cp,eval,ctx) != 0 ) + { + cp->prevtxid = txid; + return(true); + } + return(false); +} + + +uint64_t AddFaucetInputs(CMutableTransaction &mtx,CPubKey pk,uint64_t total,int32_t maxinputs); + diff --git a/src/cc/assets.cpp b/src/cc/assets.cpp index 11d375698..60268b20b 100644 --- a/src/cc/assets.cpp +++ b/src/cc/assets.cpp @@ -129,15 +129,22 @@ vout.n-1: opreturn [EVAL_ASSETS] ['E'] [assetid vin0+1] [assetid vin2] [remaining asset2 required] [origpubkey] */ -bool AssetValidate(Eval* eval,const CTransaction &tx,int32_t numvouts,uint8_t funcid,uint256 assetid,uint256 assetid2,uint64_t remaining_price,std::vector origpubkey) +bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx) { static uint256 zero; - CTxDestination address; const CTransaction vinTx; uint256 hashBlock; int32_t i,starti,numvins,preventCCvins,preventCCvouts; uint64_t nValue,assetoshis,outputs,inputs,tmpprice,totalunits,ignore; std::vector tmporigpubkey,ignorepubkey; char destaddr[64],origaddr[64],CCaddr[64]; - fprintf(stderr,"AssetValidate (%c)\n",funcid); + CTxDestination address; const CTransaction vinTx; uint256 hashBlock,assetid,assetid2; int32_t i,starti,numvins,numvouts,preventCCvins,preventCCvouts; uint64_t remaining_price,nValue,assetoshis,outputs,inputs,tmpprice,totalunits,ignore; std::vector origpubkey,tmporigpubkey,ignorepubkey; uint8_t funcid; char destaddr[64],origaddr[64],CCaddr[64]; numvins = tx.vin.size(); + numvouts = tx.vout.size(); outputs = inputs = 0; preventCCvins = preventCCvouts = -1; - if ( IsCCInput(tx.vin[0].scriptSig) != 0 ) + if ( (funcid= DecodeAssetOpRet(ctx.vout[n-1].scriptPubKey,assetid,assetid2,amount,origpubkey)) == 0 ) + return eval->Invalid("Invalid opreturn payload"); + fprintf(stderr,"AssetValidate (%c)\n",funcid); + if ( eval->GetTxUnconfirmed(assetid,createTx,hashBlock) == 0 ) + return eval->Invalid("cant find asset create txid"); + else if ( assetid2 != zero && eval->GetTxUnconfirmed(assetid2,createTx,hashBlock) == 0 ) + return eval->Invalid("cant find asset2 create txid"); + else if ( IsCCInput(tx.vin[0].scriptSig) != 0 ) return eval->Invalid("illegal asset vin0"); else if ( numvouts < 1 ) return eval->Invalid("no vouts"); @@ -314,31 +321,4 @@ bool AssetValidate(Eval* eval,const CTransaction &tx,int32_t numvouts,uint8_t fu return(PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts)); } -bool ProcessAssets(Eval* eval, std::vector paramsNull,const CTransaction &ctx, unsigned int nIn) -{ - static uint256 zero,prevtxid; - CTransaction createTx; uint256 txid,assetid,assetid2,hashBlock; uint8_t funcid; int32_t i,n; uint64_t amount; std::vector origpubkey; - txid = ctx.GetHash(); - if ( txid == prevtxid ) - return(true); - fprintf(stderr,"ProcessAssets\n"); - if ( paramsNull.size() != 0 ) // Don't expect params - return eval->Invalid("Cannot have params"); - else if ( (n= ctx.vout.size()) == 0 ) - return eval->Invalid("no-vouts"); - else if ( (funcid= DecodeAssetOpRet(ctx.vout[n-1].scriptPubKey,assetid,assetid2,amount,origpubkey)) == 0 ) - return eval->Invalid("Invalid opreturn payload"); - else if ( eval->GetTxUnconfirmed(assetid,createTx,hashBlock) == 0 ) - return eval->Invalid("cant find asset create txid"); - else if ( assetid2 != zero && eval->GetTxUnconfirmed(assetid2,createTx,hashBlock) == 0 ) - return eval->Invalid("cant find asset2 create txid"); - else if ( AssetValidate(eval,ctx,n,funcid,assetid,assetid2,amount,origpubkey) != 0 ) - { - prevtxid = txid; - fprintf(stderr,"AssetValidate.(%c) passed\n",funcid); - return(true); - } - fprintf(stderr,"AssetValidate.(%c) failed\n",funcid); - return(false); -} diff --git a/src/cc/eval.cpp b/src/cc/eval.cpp index 43b215748..2c886668d 100644 --- a/src/cc/eval.cpp +++ b/src/cc/eval.cpp @@ -21,6 +21,7 @@ #include "script/cc.h" #include "cc/eval.h" #include "cc/utils.h" +#include "cc/CCutils.h" #include "main.h" #include "chain.h" #include "core_io.h" @@ -28,12 +29,11 @@ Eval* EVAL_TEST = 0; - +struct CCcontract_info CCinfos[0x100]; bool RunCCEval(const CC *cond, const CTransaction &tx, unsigned int nIn) { EvalRef eval; - bool out = eval->Dispatch(cond, tx, nIn); //fprintf(stderr,"out %d vs %d isValid\n",(int32_t)out,(int32_t)eval->state.IsValid()); assert(eval->state.IsValid() == out); @@ -56,10 +56,17 @@ bool RunCCEval(const CC *cond, const CTransaction &tx, unsigned int nIn) */ bool Eval::Dispatch(const CC *cond, const CTransaction &txTo, unsigned int nIn) { + struct CCcontract_info *cp; if (cond->codeLength == 0) return Invalid("empty-eval"); uint8_t ecode = cond->code[0]; + cp = &CCinfos[(int32_t)ecode]; + if ( cp->didinit == 0 ) + { + CCinit(cp,ecode); + cp->didinit = 1; + } std::vector vparams(cond->code+1, cond->code+cond->codeLength); switch ( ecode ) { @@ -71,16 +78,8 @@ bool Eval::Dispatch(const CC *cond, const CTransaction &txTo, unsigned int nIn) return ImportCoin(vparams, txTo, nIn); break; - case EVAL_ASSETS: - return ProcessAssets(this, vparams, txTo, nIn); - break; - - case EVAL_FAUCET: - return ProcessFaucet(this, vparams, txTo, nIn); - break; - - case EVAL_REWARDS: - return ProcessRewards(this, vparams, txTo, nIn); + default: + return(ProcessCC(cp,this, vparams, txTo, nIn)); break; } return Invalid("invalid-code, dont forget to add EVAL_NEWCC to Eval::Dispatch"); diff --git a/src/cc/eval.h b/src/cc/eval.h index d8ca4312d..59404dba8 100644 --- a/src/cc/eval.h +++ b/src/cc/eval.h @@ -268,9 +268,8 @@ typedef std::pair TxProof; uint256 GetMerkleRoot(const std::vector& vLeaves); -bool ProcessAssets(Eval* eval, std::vector paramsNull, const CTransaction &tx, unsigned int nIn); -bool ProcessFaucet(Eval* eval, std::vector paramsNull, const CTransaction &tx, unsigned int nIn); -bool ProcessRewards(Eval* eval, std::vector paramsNull, const CTransaction &tx, unsigned int nIn); +void CCinit(struct CCcontract_info *cp,uint8_t evalcode); +bool ProcessCC(struct CCcontract_info *cp,Eval* eval, std::vector paramsNull, const CTransaction &tx, unsigned int nIn); #endif /* CC_EVAL_H */ diff --git a/src/cc/faucet.cpp b/src/cc/faucet.cpp index 15686dc01..bbce16366 100644 --- a/src/cc/faucet.cpp +++ b/src/cc/faucet.cpp @@ -37,7 +37,7 @@ uint64_t IsFaucetvout(const CTransaction& tx,int32_t v) return(0); } -bool FaucetExactAmounts(Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee) +bool FaucetExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee) { static uint256 zerohash; CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; uint64_t inputs=0,outputs=0,assetoshis; @@ -46,7 +46,7 @@ bool FaucetExactAmounts(Eval* eval,const CTransaction &tx,int32_t minage,uint64_ for (i=0; iismyvin)(tx.vin[i].scriptSig) != 0 ) { //fprintf(stderr,"vini.%d check mempool\n",i); if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 ) @@ -111,7 +111,7 @@ bool FaucetValidate(Eval* eval,const CTransaction &tx) } } -bool ProcessFaucet(Eval* eval, std::vector paramsNull,const CTransaction &ctx, unsigned int nIn) +/*bool ProcessFaucet(Eval* eval, std::vector paramsNull,const CTransaction &ctx, unsigned int nIn) { static uint256 prevtxid; uint256 txid; txid = ctx.GetHash(); @@ -130,7 +130,7 @@ bool ProcessFaucet(Eval* eval, std::vector paramsNull,const CTransactio } fprintf(stderr,"faucet validate failed\n"); return(false); -} +}*/ uint64_t AddFaucetInputs(CMutableTransaction &mtx,CPubKey pk,uint64_t total,int32_t maxinputs) { diff --git a/src/cc/rewards.cpp b/src/cc/rewards.cpp index 5253035ac..b08cd6bd7 100644 --- a/src/cc/rewards.cpp +++ b/src/cc/rewards.cpp @@ -18,34 +18,12 @@ /* */ -extern const char *RewardsCCaddr; -extern char RewardsCChexstr[67]; -bool IsRewardsInput(CScript const& scriptSig); - uint64_t RewardsCalc(uint64_t claim,uint256 txid) { uint64_t reward = 0; return(reward); } -/*CC *MakeRewardsCond(CPubKey pk) -{ - std::vector pks; uint8_t evalcode = EVAL_REWARDS; - pks.push_back(CCNewSecp256k1(pk)); - CC *rewardsCC = CCNewEval(E_MARSHAL(ss << evalcode)); - CC *Sig = CCNewThreshold(1, pks); - return CCNewThreshold(2, {rewardsCC, Sig}); -} - -CTxOut MakeRewardsVout(CAmount nValue,CPubKey pk) -{ - CTxOut vout; - CC *payoutCond = MakeCCcond1(EVAL_REWARDS,pk); - vout = CTxOut(nValue,CCPubKey(payoutCond)); - cc_free(payoutCond); - return(vout); -}*/ - uint64_t IsRewardsvout(const CTransaction& tx,int32_t v) { char destaddr[64]; @@ -57,7 +35,7 @@ uint64_t IsRewardsvout(const CTransaction& tx,int32_t v) return(0); } -bool RewardsExactAmounts(Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee) +bool RewardsExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee) { static uint256 zerohash; CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; uint64_t inputs=0,outputs=0,assetoshis; @@ -65,7 +43,7 @@ bool RewardsExactAmounts(Eval* eval,const CTransaction &tx,int32_t minage,uint64 numvouts = tx.vout.size(); for (i=0; iismyvin)(tx.vin[i].scriptSig) != 0 ) { if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 ) return eval->Invalid("always should find vin, but didnt"); @@ -92,7 +70,7 @@ bool RewardsExactAmounts(Eval* eval,const CTransaction &tx,int32_t minage,uint64 else return(true); } -bool RewardsValidate(Eval* eval,const CTransaction &tx) +bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx) { int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; numvins = tx.vin.size(); @@ -107,7 +85,7 @@ bool RewardsValidate(Eval* eval,const CTransaction &tx) if ( IsCCInput(tx.vin[0].scriptSig) == 0 ) return eval->Invalid("illegal normal vini"); } - if ( RewardsExactAmounts(eval,tx,1,10000) == false ) + if ( RewardsExactAmounts(cp,eval,tx,1,10000) == false ) return false; else { @@ -125,7 +103,7 @@ bool RewardsValidate(Eval* eval,const CTransaction &tx) return(true); } -bool ProcessRewards(Eval* eval, std::vector paramsNull,const CTransaction &ctx, unsigned int nIn) +/*bool ProcessRewards(Eval* eval, std::vector paramsNull,const CTransaction &ctx, unsigned int nIn) { static uint256 prevtxid; uint256 txid; txid = ctx.GetHash(); @@ -144,7 +122,7 @@ bool ProcessRewards(Eval* eval, std::vector paramsNull,const CTransacti } fprintf(stderr,"ProcessRewards failed\n"); return(false); -} +}*/ uint64_t AddRewardsInputs(CMutableTransaction &mtx,CPubKey pk,uint64_t total,int32_t maxinputs) { diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index c79226954..ac202298d 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4842,10 +4842,7 @@ int32_t ensure_CCrequirements() #include "../cc/CCfaucet.h" #include "../cc/CCassets.h" -#define EVAL_REWARDS 0xe5 -std::string RewardsFund(uint64_t txfee,uint64_t funds,uint64_t APR,uint64_t minseconds,uint64_t maxseconds,uint64_t mindeposit); -std::string RewardsLock(uint64_t txfee,uint64_t amount); -std::string RewardsUnlock(uint64_t txfee); +#include "../cc/CCrewards.h" UniValue rewardsaddress(const UniValue& params, bool fHelp) {