diff --git a/src/cc/CCinclude.h b/src/cc/CCinclude.h index fe1ba7a6c..0f0348ebb 100644 --- a/src/cc/CCinclude.h +++ b/src/cc/CCinclude.h @@ -75,5 +75,6 @@ std::string FinalizeCCTx(struct CCcontract_info *cp,CMutableTransaction &mtx,CPu void SetCCunspents(std::vector > &unspentOutputs,char *coinaddr); void SetCCtxids(std::vector > &addressIndex,char *coinaddr); uint64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,uint64_t total,int32_t maxinputs); +uint64_t CCutxovalue(char *coinaddr,uint256 utxotxid,int32_t utxovout); #endif diff --git a/src/cc/CCtx.cpp b/src/cc/CCtx.cpp index 7b8aaa866..1620773ee 100644 --- a/src/cc/CCtx.cpp +++ b/src/cc/CCtx.cpp @@ -182,6 +182,19 @@ void SetCCtxids(std::vector > &addressIndex } } +uint64_t CCutxovalue(char *coinaddr,uint256 utxotxid,int32_t utxovout) +{ + uint256 txid; std::vector > unspentOutputs; + SetCCunspents(unspentOutputs,coinaddr); + for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) + { + txid = it->first.txhash; + if ( txid == utxotxid && utxovout == it->first.index ) + return(it->second.satoshis); + } + return(0); +} + uint64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,uint64_t total,int32_t maxinputs) { int32_t vout,j,n = 0; uint64_t nValue,totalinputs = 0; uint256 txid; std::vector vecOutputs; diff --git a/src/cc/CCutils.cpp b/src/cc/CCutils.cpp index 039f5cbd9..b68d1061b 100644 --- a/src/cc/CCutils.cpp +++ b/src/cc/CCutils.cpp @@ -268,5 +268,3 @@ bool ProcessCC(struct CCcontract_info *cp,Eval* eval, std::vector param return(false); } - - diff --git a/src/cc/rewards.cpp b/src/cc/rewards.cpp index fc1f1a036..fd43e2667 100644 --- a/src/cc/rewards.cpp +++ b/src/cc/rewards.cpp @@ -299,44 +299,6 @@ UniValue RewardsList() return(result); } -std::string RewardsUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 locktxid) -{ - CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; uint64_t funding,sbits,reward,amount=0,inputs,CCchange=0,APR,minseconds,maxseconds,mindeposit; struct CCcontract_info *cp,C; - cp = CCinit(&C,EVAL_REWARDS); - if ( txfee == 0 ) - txfee = 10000; - rewardspk = GetUnspendable(cp,0); - mypk = pubkey2pk(Mypubkey()); - sbits = stringbits(planstr); - if ( RewardsPlanExists(cp,sbits,rewardspk,APR,minseconds,maxseconds,mindeposit) == 0 ) - { - fprintf(stderr,"Rewards plan %s doesnt exist\n",planstr); - return(0); - } - if ( locktxid == zeroid ) - amount = AddRewardsInputs(cp,mtx,rewardspk,(1LL << 30),1); - else - { - fprintf(stderr,"check if locktxid is unspent\n"); - return(0); - } - if ( amount > 0 && (reward= RewardsCalc(amount,mtx.vin[0].prevout.hash,APR,minseconds,maxseconds,mindeposit)) > txfee ) - { - if ( (inputs= AddRewardsInputs(cp,mtx,mypk,reward+amount+txfee,30)) > 0 ) - { - if ( inputs >= (amount + reward + 2*txfee) ) - CCchange = (inputs - (amount + reward + txfee)); - if ( CCchange != 0 ) - mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange,rewardspk)); - mtx.vout.push_back(CTxOut(amount+reward,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - return(FinalizeCCTx(cp,mtx,mypk,txfee,EncodeRewardsOpRet('U',sbits,fundingtxid))); - } - fprintf(stderr,"cant find enough rewards inputs\n"); - } - fprintf(stderr,"cant find rewards inputs\n"); - return(0); -} - std::string RewardsCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t APR,int64_t minseconds,int64_t maxseconds,int64_t mindeposit) { CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; uint64_t sbits,a,b,c,d; struct CCcontract_info *cp,C; @@ -425,10 +387,52 @@ std::string RewardsLock(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t { mtx.vout.push_back(MakeCC1vout(cp->evalcode,deposit,rewardspk)); return(FinalizeCCTx(cp,mtx,mypk,txfee,EncodeRewardsOpRet('L',sbits,fundingtxid))); - } else fprintf(stderr,"cant find enough inputs\n"); + } else fprintf(stderr,"cant find enough inputs %.8f note enough for %.8f\n",(double)funding/COIN,(double)deposit/COIN); } fprintf(stderr,"cant find rewards inputs\n"); return(0); } +std::string RewardsUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 locktxid) +{ + CMutableTransaction mtx; char coinaddr[64]; CPubKey mypk,rewardspk; CScript opret; uint64_t funding,sbits,reward,amount=0,inputs,CCchange=0,APR,minseconds,maxseconds,mindeposit; struct CCcontract_info *cp,C; + cp = CCinit(&C,EVAL_REWARDS); + if ( txfee == 0 ) + txfee = 10000; + rewardspk = GetUnspendable(cp,0); + mypk = pubkey2pk(Mypubkey()); + sbits = stringbits(planstr); + if ( RewardsPlanExists(cp,sbits,rewardspk,APR,minseconds,maxseconds,mindeposit) == 0 ) + { + fprintf(stderr,"Rewards plan %s doesnt exist\n",planstr); + return(0); + } + if ( locktxid == zeroid ) + amount = AddRewardsInputs(cp,mtx,rewardspk,(1LL << 30),1); + else + { + GetCCaddress(cp,coinaddr,mypk); + if ( (amount= CCutxovalue(coinaddr,locktxid,0)) == 0 ) + { + fprintf(stderr,"locktxid/v0 is spent\n"); + return(0); + } + mtx.vin.push_back(CTxIn(locktxid,0,CScript())); + } + if ( amount > 0 && (reward= RewardsCalc(amount,mtx.vin[0].prevout.hash,APR,minseconds,maxseconds,mindeposit)) > txfee ) + { + if ( (inputs= AddRewardsInputs(cp,mtx,mypk,reward+amount+txfee,30)) > 0 ) + { + if ( inputs >= (amount + reward + 2*txfee) ) + CCchange = (inputs - (amount + reward + txfee)); + if ( CCchange != 0 ) + mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange,rewardspk)); + mtx.vout.push_back(CTxOut(amount+reward,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); + return(FinalizeCCTx(cp,mtx,mypk,txfee,EncodeRewardsOpRet('U',sbits,fundingtxid))); + } + fprintf(stderr,"cant find enough rewards inputs\n"); + } + fprintf(stderr,"amount %.8f -> reward %.8f\n",(double)amount/COIN,(double)reward/COIN); + return(0); +}