From cfea7a4690190628a29d0bed00e363b86bbe5232 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 24 Jul 2018 07:13:05 -1100 Subject: [PATCH] Dice skeleton --- src/cc/CCcustom.cpp | 17 ++++ src/cc/CCdice.h | 29 +++++++ src/cc/CCinclude.h | 2 + src/cc/CCrewards.h | 4 +- src/cc/CCutils.cpp | 24 ++++++ src/cc/assets.cpp | 2 +- src/cc/dice.cpp | 182 +++++++++++++++++++++++++++++++++++++++ src/cc/rewards.cpp | 101 ++++++++++++++++------ src/rpcserver.cpp | 7 +- src/rpcserver.h | 3 + src/wallet/rpcwallet.cpp | 147 +++++++++++++++++++------------ 11 files changed, 434 insertions(+), 84 deletions(-) create mode 100644 src/cc/CCdice.h create mode 100644 src/cc/dice.cpp diff --git a/src/cc/CCcustom.cpp b/src/cc/CCcustom.cpp index d15e43a02..f4642c82e 100644 --- a/src/cc/CCcustom.cpp +++ b/src/cc/CCcustom.cpp @@ -71,6 +71,16 @@ uint8_t RewardsCCpriv[32] = { 0x9f, 0x0c, 0x57, 0xdc, 0x6f, 0x78, 0xae, 0xb0, 0x #undef FUNCNAME #undef EVALCODE +// Dice +#define FUNCNAME IsDiceInput +#define EVALCODE EVAL_DICE +const char *DiceCCaddr = "RJCqA4jQTFEZ841dZgxko8aYgUU3FRNGNm" ;//"RYRJGMAYEfLCZ6ZddbpxPiUZ1sens8vPYK"; +char DiceCChexstr[67] = { "026f00fdc2f1ed0006d66e2ca1787633590581c2fc90e7cb7b01a6c1131b40e94d" }; +uint8_t DiceCCpriv[32] = { 0x9f, 0x0c, 0x57, 0xdc, 0x6f, 0x78, 0xae, 0xb0, 0xc7, 0x62, 0x9e, 0x7d, 0x2b, 0x90, 0x6b, 0xbd, 0x40, 0x78, 0x19, 0x5b, 0x3c, 0xb8, 0x82, 0x2d, 0x29, 0x84, 0x72, 0x7a, 0x59, 0x5a, 0x4b, 0x69 }; +#include "CCcustom.inc" +#undef FUNCNAME +#undef EVALCODE + struct CCcontract_info *CCinit(struct CCcontract_info *cp,uint8_t evalcode) { cp->evalcode = evalcode; @@ -97,6 +107,13 @@ struct CCcontract_info *CCinit(struct CCcontract_info *cp,uint8_t evalcode) cp->validate = RewardsValidate; cp->ismyvin = IsRewardsInput; break; + case EVAL_DICE: + strcpy(cp->unspendableCCaddr,DiceCCaddr); + strcpy(cp->CChexstr,DiceCChexstr); + memcpy(cp->CCpriv,DiceCCpriv,32); + cp->validate = DiceValidate; + cp->ismyvin = IsDiceInput; + break; } return(cp); } diff --git a/src/cc/CCdice.h b/src/cc/CCdice.h new file mode 100644 index 000000000..582a9fe64 --- /dev/null +++ b/src/cc/CCdice.h @@ -0,0 +1,29 @@ +/****************************************************************************** + * 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_DICE 0xe6 + +bool DiceValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); + +std::string DiceFund(uint64_t txfee,uint64_t funds); +std::string DiceBet(uint64_t txfee,uint64_t amount,uint64_t odds) + +#endif diff --git a/src/cc/CCinclude.h b/src/cc/CCinclude.h index b10b64478..f72fce237 100644 --- a/src/cc/CCinclude.h +++ b/src/cc/CCinclude.h @@ -54,6 +54,8 @@ CTxOut MakeCC1vout(uint8_t evalcode,CAmount nValue,CPubKey pk); CC *MakeCCcond1(uint8_t evalcode,CPubKey pk); CC* GetCryptoCondition(CScript const& scriptSig); bool IsCCInput(CScript const& scriptSig); +int32_t unstringbits(char *buf,uint64_t bits); +uint64_t stringbits(char *str); uint256 revuint256(uint256 txid); char *uint256_str(char *dest,uint256 txid); uint256 Parseuint256(char *hexstr); diff --git a/src/cc/CCrewards.h b/src/cc/CCrewards.h index fe900c02b..35fe87960 100644 --- a/src/cc/CCrewards.h +++ b/src/cc/CCrewards.h @@ -23,8 +23,8 @@ 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 RewardsFund(uint64_t txfee,char *planstr,uint64_t funds,uint64_t APR,uint64_t minseconds,uint64_t maxseconds,uint64_t mindeposit); +std::string RewardsLock(uint64_t txfee,char *planstr,uint64_t amount) std::string RewardsUnlock(uint64_t txfee); #endif diff --git a/src/cc/CCutils.cpp b/src/cc/CCutils.cpp index 80a2e5af6..f8617e536 100644 --- a/src/cc/CCutils.cpp +++ b/src/cc/CCutils.cpp @@ -55,6 +55,30 @@ bool IsCCInput(CScript const& scriptSig) return true; } +int32_t unstringbits(char *buf,uint64_t bits) +{ + int32_t i; + for (i=0; i<8; i++,bits>>=8) + if ( (buf[i]= (char)(bits & 0xff)) == 0 ) + break; + buf[i] = 0; + return(i); +} + +uint64_t stringbits(char *str) +{ + uint64_t bits = 0; + if ( str == 0 ) + return(0); + int32_t i,n = (int32_t)strlen(str); + if ( n > 8 ) + n = 8; + for (i=n-1; i>=0; i--) + bits = (bits << 8) | (str[i] & 0xff); + //printf("(%s) -> %llx %llu\n",str,(long long)bits,(long long)bits); + return(bits); +} + uint256 revuint256(uint256 txid) { uint256 revtxid; int32_t i; diff --git a/src/cc/assets.cpp b/src/cc/assets.cpp index b1a34d524..8462c0b16 100644 --- a/src/cc/assets.cpp +++ b/src/cc/assets.cpp @@ -48,7 +48,7 @@ create vin.0: normal input vout.0: issuance assetoshis to CC - vout.1: tag sent to AssetsCCaddress + vout.1: tag sent to normal address of AssetsCCaddress vout.2: normal output for change (if any) vout.n-1: opreturn [EVAL_ASSETS] ['c'] [origpubkey] "" "" diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp new file mode 100644 index 000000000..f76fc02ab --- /dev/null +++ b/src/cc/dice.cpp @@ -0,0 +1,182 @@ +/****************************************************************************** + * 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. * + * * + ******************************************************************************/ + +#include "CCdice.h" +#include "../txmempool.h" + +/* +*/ + +// start of consensus code + +uint64_t IsDicevout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v) +{ + char destaddr[64]; + if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) + { + if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 ) + return(tx.vout[v].nValue); + } + return(0); +} + +bool DiceExactAmounts(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; + numvins = tx.vin.size(); + numvouts = tx.vout.size(); + 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 ) + return eval->Invalid("cant find vinTx"); + else + { + //fprintf(stderr,"vini.%d check hash and vout\n",i); + if ( hashBlock == zerohash ) + return eval->Invalid("cant dice from mempool"); + if ( (assetoshis= IsDicevout(cp,vinTx,tx.vin[i].prevout.n)) != 0 ) + inputs += assetoshis; + } + } + } + for (i=0; iInvalid("mismatched inputs != outputs + COIN + txfee"); + } + else return(true); +} + +bool DiceValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx) +{ + int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; bool retval; + numvins = tx.vin.size(); + numvouts = tx.vout.size(); + preventCCvins = preventCCvouts = -1; + if ( numvouts < 1 ) + return eval->Invalid("no vouts"); + else + { + //fprintf(stderr,"check vins\n"); + for (i=0; iInvalid("illegal normal vini"); + } + } + //fprintf(stderr,"check amounts\n"); + if ( DiceExactAmounts(cp,eval,tx,1,10000) == false ) + { + fprintf(stderr,"diceget invalid amount\n"); + return false; + } + else + { + preventCCvouts = 1; + if ( IsDicevout(cp,tx,0) != 0 ) + { + preventCCvouts++; + i = 1; + } else i = 0; + if ( tx.vout[i].nValue != COIN ) + return eval->Invalid("invalid dice output"); + retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts); + if ( retval != 0 ) + fprintf(stderr,"diceget validated\n"); + else fprintf(stderr,"diceget invalid\n"); + return(retval); + } + } +} +// end of consensus code + +// helper functions for rpc calls in rpcwallet.cpp + +uint64_t AddDiceInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint64_t total,int32_t maxinputs) +{ + char coinaddr[64]; uint64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector origpubkey; CTransaction vintx; int32_t n = 0; + std::vector > unspentOutputs; + GetCCaddress(cp,coinaddr,pk); + SetCCunspents(unspentOutputs,coinaddr); + for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) + { + txid = it->first.txhash; + if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) + { + if ( (nValue= IsDicevout(cp,vintx,(int32_t)it->first.index)) > 0 ) + { + if ( total != 0 && maxinputs != 0 ) + mtx.vin.push_back(CTxIn(txid,(int32_t)it->first.index,CScript())); + nValue = it->second.satoshis; + totalinputs += nValue; + n++; + if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) + break; + } + } + } + return(totalinputs); +} + +std::string DiceBet(uint64_t txfee,uint64_t amount,uint64_t odds) +{ + CMutableTransaction mtx; CPubKey mypk,dicepk; CScript opret; uint64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C; + cp = CCinit(&C,EVAL_DICE); + if ( txfee == 0 ) + txfee = 10000; + dicepk = GetUnspendable(cp,0); + mypk = pubkey2pk(Mypubkey()); + if ( (inputs= AddDiceInputs(cp,mtx,dicepk,nValue+txfee,60)) > 0 ) + { + if ( inputs > nValue ) + CCchange = (inputs - nValue - txfee); + if ( CCchange != 0 ) + mtx.vout.push_back(MakeCC1vout(EVAL_DICE,CCchange,dicepk)); + mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); + return(FinalizeCCTx(cp,mtx,mypk,txfee,opret)); + } else fprintf(stderr,"cant find dice inputs\n"); + return(0); +} + +std::string DiceFund(uint64_t txfee,uint64_t funds) +{ + CMutableTransaction mtx; CPubKey mypk,dicepk; CScript opret; struct CCcontract_info *cp,C; + cp = CCinit(&C,EVAL_DICE); + if ( txfee == 0 ) + txfee = 10000; + mypk = pubkey2pk(Mypubkey()); + dicepk = GetUnspendable(cp,0); + if ( AddNormalinputs(mtx,mypk,funds+txfee,64) > 0 ) + { + mtx.vout.push_back(MakeCC1vout(EVAL_DICE,funds,dicepk)); + return(FinalizeCCTx(cp,mtx,mypk,txfee,opret)); + } + return(0); +} + + diff --git a/src/cc/rewards.cpp b/src/cc/rewards.cpp index fe1583303..7ec3b83e6 100644 --- a/src/cc/rewards.cpp +++ b/src/cc/rewards.cpp @@ -16,11 +16,34 @@ #include "CCinclude.h" /* + The rewards CC contract is initially for OOT, which needs this functionality. However, many of the attributes can be parameterized to allow different rewards programs to run. Multiple rewards plans could even run on the same blockchain, though the user would need to choose which one to lock funds into. + + At the high level, the user would lock funds for some amount of time and at the end of it, would get all the locked funds back with an additional reward. So there needs to be a lock funds and unlock funds ability. Additionally, the rewards need to come from somewhere, so similar to the faucet, there would be a way to fund the reward. + + Additional requirements are for the user to be able to lock funds via SPV. This requirement in turns forces the creation of a way for anybody to be able to unlock the funds as that operation requires a native daemon running and cant be done over SPV. The idea is to allow anybody to run a script that would unlock all funds that are matured. As far as the user is concerned, he locks his funds via SPV and after some time it comes back with an extra reward. + + In reality, the funds are locked into a CC address that is unspendable, except for some special conditions and it needs to come back to the address that funded the lock. In order to implement this, several things are clear. + + 1) each locked CC utxo needs to be linked to a specific rewards plan + 2) each locked CC utxo needs to know the only address that it can be unlocked into + 3) SPV requirement means the lock transaction needs to be able to be created without any CC signing + + The opreturn will be used to store the name of the rewards plan and all funding and locked funds with the same plan will use the same pool of rewards. plan names will be limited to 8 chars and encoded into a uint64_t. + + The initial funding transaction will have all the parameters for the rewards plan encoded in the vouts. Additional fundings will just increase the available CC utxo for the rewards. + + Locks wont have any CC vins, but will send to the RewardsCCaddress, with the plan stringbits in the opreturn. vout1 will have the unlock address and no other destination is valid. + + Unlock does a CC spend to the vout1 address */ -uint64_t RewardsCalc(uint64_t claim,uint256 txid) +uint64_t RewardsCalc(uint64_t claim,uint256 txid) // min/max time, mindeposit and rate { uint64_t reward = 0; + // get start time, get current time + // if elapsed < mintime -> return 0 + // if elapsed > maxtime, elapsed = maxtime + // calc reward return(reward); } @@ -80,6 +103,7 @@ bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t return eval->Invalid("no vouts"); else { + // follow rules for (i=0; i origpubkey; CTransaction vintx; int32_t n = 0; + char coinaddr[64]; uint64_t nValue,totalinputs = 0; uint256 txid,hashBlock; CTransaction vintx; int32_t n = 0; std::vector > unspentOutputs; GetCCaddress(cp,coinaddr,pk); SetCCunspents(unspentOutputs,coinaddr); @@ -118,8 +142,7 @@ uint64_t AddRewardsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP { if ( total != 0 && maxinputs != 0 ) mtx.vin.push_back(CTxIn(txid,(int32_t)it->first.index,CScript())); - nValue = it->second.satoshis; - totalinputs += nValue; + totalinputs += it->second.satoshis; n++; if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) break; @@ -129,34 +152,55 @@ uint64_t AddRewardsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP return(totalinputs); } +uint64_t RewardsPlanFunds(uint64_t &refsbits,struct CCcontract_info *cp,CPubKey &pk,char *planstr) +{ + char coinaddr[64]; uint64_t sbits,totalinputs = 0; uint256 hashBlock; CTransaction vintx; + std::vector > unspentOutputs; + if ( planstr == 0 || planstr[0] == 0 || strlen(planstr) > 8 ) + return(0); + refsbits = stringbits(planstr); + GetCCaddress(cp,coinaddr,pk); + SetCCunspents(unspentOutputs,coinaddr); + for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) + { + if ( GetTransaction(it->first.txhash,vintx,hashBlock,false) != 0 ) + { + xxx if ( (nValue= IsRewardsvout(cp,vintx,(int32_t)it->first.index)) > 0 ) + { + totalinputs += nValue; + } + } + } + return(totalinputs); +} + std::string RewardsUnlock(uint64_t txfee) { - CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; uint64_t reward,claim,inputs,CCchange=0; struct CCcontract_info *cp,C; + CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; uint64_t reward,amount,inputs,CCchange=0; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_REWARDS); if ( txfee == 0 ) txfee = 10000; rewardspk = GetUnspendable(cp,0); mypk = pubkey2pk(Mypubkey()); - if ( (claim= AddRewardsInputs(cp,mtx,mypk,(1LL << 30),1)) > 0 && (reward= RewardsCalc(claim,mtx.vin[0].prevout.hash)) > txfee ) + if ( (amount= AddRewardsInputs(cp,mtx,mypk,(1LL << 30),1)) > 0 && (reward= RewardsCalc(claim,mtx.vin[0].prevout.hash)) > txfee ) { - if ( (inputs= AddRewardsInputs(cp,mtx,mypk,reward+txfee,30)) > 0 ) + if ( (inputs= AddRewardsInputs(cp,mtx,mypk,reward+amount+txfee,30)) > 0 ) { - if ( inputs > (reward+txfee) ) - CCchange = (inputs - reward - txfee); + if ( inputs > (amount + reward + 2*txfee) ) + CCchange = (inputs - amount - reward - txfee); if ( CCchange != 0 ) - mtx.vout.push_back(MakeCC1vout(EVAL_REWARDS,CCchange,rewardspk)); - mtx.vout.push_back(CTxOut(claim+reward,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); + mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange,rewardspk)); + mtx.vout.push_back(CTxOut(amount+reward,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); + opret << OP_RETURN << E_MARSHAL(ss << cp->evalcode << 'U' << sbits); return(FinalizeCCTx(cp,mtx,mypk,txfee,opret)); } } else fprintf(stderr,"cant find rewards inputs\n"); return(0); } -// 0.834% every 60 days, min 100, capped at 0.834% - -std::string RewardsFund(uint64_t txfee,uint64_t funds,uint64_t APR,uint64_t minseconds,uint64_t maxseconds,uint64_t mindeposit) +std::string RewardsFund(uint64_t txfee,char *planstr,uint64_t funds,uint64_t APR,uint64_t minseconds,uint64_t maxseconds,uint64_t mindeposit) { - CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; struct CCcontract_info *cp,C; + CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; uint64_t sbits; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_REWARDS); if ( txfee == 0 ) txfee = 10000; @@ -164,31 +208,34 @@ std::string RewardsFund(uint64_t txfee,uint64_t funds,uint64_t APR,uint64_t mins rewardspk = GetUnspendable(cp,0); if ( AddNormalinputs(mtx,mypk,funds+2*txfee,64) > 0 ) { - mtx.vout.push_back(MakeCC1vout(EVAL_REWARDS,funds,rewardspk)); + mtx.vout.push_back(MakeCC1vout(cp->evalcode,funds,rewardspk)); mtx.vout.push_back(CTxOut(APR,CScript() << ParseHex(HexStr(rewardspk)) << OP_CHECKSIG)); mtx.vout.push_back(CTxOut(minseconds,CScript() << ParseHex(HexStr(rewardspk)) << OP_CHECKSIG)); mtx.vout.push_back(CTxOut(maxseconds,CScript() << ParseHex(HexStr(rewardspk)) << OP_CHECKSIG)); mtx.vout.push_back(CTxOut(mindeposit,CScript() << ParseHex(HexStr(rewardspk)) << OP_CHECKSIG)); + opret << OP_RETURN << E_MARSHAL(ss << cp->evalcode << 'F' << sbits); return(FinalizeCCTx(cp,mtx,mypk,txfee,opret)); } return(0); } -std::string RewardsLock(uint64_t txfee,uint64_t amount) +std::string RewardsLock(uint64_t txfee,char *planstr,uint64_t amount) { - CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; struct CCcontract_info *cp,C; + CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; uint64_t sbits,funding; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_REWARDS); - if ( txfee == 0 ) - txfee = 10000; - rewardspk = GetUnspendable(cp,0); mypk = pubkey2pk(Mypubkey()); - if ( AddNormalinputs(mtx,mypk,amount+2*txfee,64) > 0 ) + rewardspk = GetUnspendable(cp,0); + if ( (funding= RewardsPlanFunds(sbits,cp,rewardspk,planstr)) >= amount ) { - mtx.vout.push_back(MakeCC1vout(EVAL_REWARDS,amount,rewardspk)); - // specify destination pubkey, funding txid - //opret = ;// - return(FinalizeCCTx(cp,mtx,mypk,txfee,opret)); - } else fprintf(stderr,"cant find rewards inputs\n"); + if ( txfee == 0 ) + txfee = 10000; + if ( AddNormalinputs(mtx,mypk,amount+txfee,64) > 0 ) + { + mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,rewardspk)); + opret << OP_RETURN << E_MARSHAL(ss << cp->evalcode << 'L' << sbits); + return(FinalizeCCTx(cp,mtx,mypk,txfee,opret)); + } else fprintf(stderr,"cant find rewards inputs\n"); + } return(0); } diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 4d766d5ae..40ebd162c 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -354,8 +354,13 @@ static const CRPCCommand vRPCCommands[] = { "faucet", "faucetfund", &faucetfund, true }, { "faucet", "faucetget", &faucetget, true }, { "faucet", "faucetaddress", &faucetaddress, true }, + + /* dice */ + { "dice", "dicefund", &dicefund, true }, + { "dice", "dicebet", &dicebet, true }, + { "dice", "diceaddress", &diceaddress, true }, -/* tokens */ + /* tokens */ { "tokens", "tokenorders", &tokenorders, true }, { "tokens", "tokenaddress", &tokenaddress, true }, { "tokens", "tokenbalance", &tokenbalance, true }, diff --git a/src/rpcserver.h b/src/rpcserver.h index eb9f69247..ff06966ba 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -228,6 +228,9 @@ extern UniValue rewardsaddress(const UniValue& params, bool fHelp); extern UniValue rewardsfund(const UniValue& params, bool fHelp); extern UniValue rewardslock(const UniValue& params, bool fHelp); extern UniValue rewardsunlock(const UniValue& params, bool fHelp); +extern UniValue diceaddress(const UniValue& params, bool fHelp); +extern UniValue dicefund(const UniValue& params, bool fHelp); +extern UniValue dicebet(const UniValue& params, bool fHelp); extern UniValue getnewaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp //extern UniValue getnewaddress64(const UniValue& params, bool fHelp); // in rpcwallet.cpp diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 5d92a585f..e10a7b09b 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4843,21 +4843,17 @@ int32_t ensure_CCrequirements() #include "../cc/CCfaucet.h" #include "../cc/CCassets.h" #include "../cc/CCrewards.h" +#include "../cc/CCdice.h" -UniValue rewardsaddress(const UniValue& params, bool fHelp) +UniValue CCaddress(struct CCcontract_info *cp,char *name,std::vector &pubkey) { - UniValue result(UniValue::VOBJ); std::vector pubkey; char destaddr[64]; struct CCcontract_info *cp,C; - cp = CCinit(&C,EVAL_REWARDS); - if ( fHelp || params.size() > 1 ) - throw runtime_error("rewardsaddress [pubkey]\n"); - if ( ensure_CCrequirements() < 0 ) - throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + UniValue result(UniValue::VOBJ); ; char destaddr[64],str[64]; result.push_back(Pair("result", "success")); + sprintf(str,"%sCCaddress",name); if ( GetCCaddress(cp,destaddr,pubkey2pk(pubkey)) != 0 ) - result.push_back(Pair("RewardsCCaddress",destaddr)); - if ( params.size() == 1 ) + result.push_back(Pair(str,destaddr)); + if ( pubkey.size() == 33 ) { - pubkey = ParseHex(params[0].get_str().c_str()); if ( GetCCaddress(cp,destaddr,pubkey2pk(pubkey)) != 0 ) result.push_back(Pair("CCaddress",destaddr)); } @@ -4866,6 +4862,58 @@ UniValue rewardsaddress(const UniValue& params, bool fHelp) return(result); } +UniValue diceaddress(const UniValue& params, bool fHelp) +{ + struct CCcontract_info *cp,C; std::vector pubkey; + cp = CCinit(&C,EVAL_REWARDS); + if ( fHelp || params.size() > 1 ) + throw runtime_error("diceaddress [pubkey]\n"); + if ( ensure_CCrequirements() < 0 ) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + if ( params.size() == 1 ) + pubkey = ParseHex(params[0].get_str().c_str()); + return(CCaddress(cp,"Dice",pubkey)); +} + +UniValue faucetaddress(const UniValue& params, bool fHelp) +{ + struct CCcontract_info *cp,C; std::vector pubkey; + cp = CCinit(&C,EVAL_REWARDS); + if ( fHelp || params.size() > 1 ) + throw runtime_error("faucetaddress [pubkey]\n"); + if ( ensure_CCrequirements() < 0 ) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + if ( params.size() == 1 ) + pubkey = ParseHex(params[0].get_str().c_str()); + return(CCaddress(cp,"Faucet",pubkey)); +} + +UniValue rewardsaddress(const UniValue& params, bool fHelp) +{ + struct CCcontract_info *cp,C; std::vector pubkey; + cp = CCinit(&C,EVAL_REWARDS); + if ( fHelp || params.size() > 1 ) + throw runtime_error("rewardsaddress [pubkey]\n"); + if ( ensure_CCrequirements() < 0 ) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + if ( params.size() == 1 ) + pubkey = ParseHex(params[0].get_str().c_str()); + return(CCaddress(cp,"Rewards",pubkey)); +} + +UniValue tokenaddress(const UniValue& params, bool fHelp) +{ + struct CCcontract_info *cp,C; std::vector pubkey; + cp = CCinit(&C,EVAL_REWARDS); + if ( fHelp || params.size() > 1 ) + throw runtime_error("tokenaddress [pubkey]\n"); + if ( ensure_CCrequirements() < 0 ) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + if ( params.size() == 1 ) + pubkey = ParseHex(params[0].get_str().c_str()); + return(CCaddress(cp,"Assets",pubkey)); +} + UniValue rewardsfund(const UniValue& params, bool fHelp) { UniValue result(UniValue::VOBJ); uint64_t funds,APR,minseconds,maxseconds,mindeposit; std::string hex; @@ -4934,29 +4982,40 @@ UniValue rewardsunlock(const UniValue& params, bool fHelp) return(result); } -UniValue faucetaddress(const UniValue& params, bool fHelp) +UniValue faucetfund(const UniValue& params, bool fHelp) { - UniValue result(UniValue::VOBJ); std::vector pubkey; char destaddr[64]; struct CCcontract_info *cp,C; - cp = CCinit(&C,EVAL_FAUCET); + UniValue result(UniValue::VOBJ); uint64_t funds; std::string hex; if ( fHelp || params.size() > 1 ) - throw runtime_error("faucetaddress [pubkey]\n"); + throw runtime_error("faucetfund amount\n"); if ( ensure_CCrequirements() < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); - result.push_back(Pair("result", "success")); - if ( GetCCaddress(cp,destaddr,pubkey2pk(pubkey)) != 0 ) - result.push_back(Pair("FaucetCCaddress",destaddr)); - if ( params.size() == 1 ) + funds = atof(params[0].get_str().c_str()) * COIN; + hex = FaucetFund(0,funds); + if ( hex.size() > 0 ) { - pubkey = ParseHex(params[0].get_str().c_str()); - if ( GetCCaddress(cp,destaddr,pubkey2pk(pubkey)) != 0 ) - result.push_back(Pair("CCaddress",destaddr)); - } - if ( GetCCaddress(cp,destaddr,pubkey2pk(Mypubkey())) != 0 ) - result.push_back(Pair("myCCaddress",destaddr)); + result.push_back(Pair("result", "success")); + result.push_back(Pair("hex", hex)); + } else result.push_back(Pair("error", "couldnt create faucet funding transaction")); return(result); } -UniValue faucetfund(const UniValue& params, bool fHelp) +UniValue faucetget(const UniValue& params, bool fHelp) +{ + UniValue result(UniValue::VOBJ); std::string hex; + if ( fHelp || params.size() > 0 ) + throw runtime_error("faucetget\n"); + if ( ensure_CCrequirements() < 0 ) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + hex = FaucetGet(0); + if ( hex.size() > 0 ) + { + result.push_back(Pair("result", "success")); + result.push_back(Pair("hex", hex)); + } else result.push_back(Pair("error", "couldnt create faucet get transaction")); + return(result); +} + +UniValue dicefund(const UniValue& params, bool fHelp) { UniValue result(UniValue::VOBJ); uint64_t funds; std::string hex; if ( fHelp || params.size() > 1 ) @@ -4964,7 +5023,7 @@ UniValue faucetfund(const UniValue& params, bool fHelp) if ( ensure_CCrequirements() < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); funds = atof(params[0].get_str().c_str()) * COIN; - hex = FaucetFund(0,funds); + hex = DiceFund(0,funds); if ( hex.size() > 0 ) { result.push_back(Pair("result", "success")); @@ -4973,14 +5032,18 @@ UniValue faucetfund(const UniValue& params, bool fHelp) return(result); } -UniValue faucetget(const UniValue& params, bool fHelp) +UniValue dicebet(const UniValue& params, bool fHelp) { - UniValue result(UniValue::VOBJ); std::string hex; - if ( fHelp || params.size() > 0 ) - throw runtime_error("faucetget\n"); + UniValue result(UniValue::VOBJ); std::string hex; uint64_t amount,odds; + if ( fHelp || params.size() > 2 ) + throw runtime_error("dicebet amount odds\n"); if ( ensure_CCrequirements() < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); - hex = FaucetGet(0); + amount = atof(params[0].get_str().c_str()) * COIN; + if ( params.size() == 2 ) + odds = atof(params[1].get_str().c_str()) * COIN; + else odds = 1; + hex = DiceBet(0,amount,odds); if ( hex.size() > 0 ) { result.push_back(Pair("result", "success")); @@ -5023,28 +5086,6 @@ UniValue tokenbalance(const UniValue& params, bool fHelp) return(result); } -UniValue tokenaddress(const UniValue& params, bool fHelp) -{ - UniValue result(UniValue::VOBJ); std::vector pubkey; char destaddr[64]; struct CCcontract_info *cp,C; - cp = CCinit(&C,EVAL_ASSETS); - if ( fHelp || params.size() > 1 ) - throw runtime_error("tokenaddress [pubkey]\n"); - if ( ensure_CCrequirements() < 0 ) - throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); - result.push_back(Pair("result", "success")); - if ( GetCCaddress(cp,destaddr,pubkey2pk(pubkey)) != 0 ) - result.push_back(Pair("AssetsCCaddress",destaddr)); - if ( params.size() == 1 ) - { - pubkey = ParseHex(params[0].get_str().c_str()); - if ( GetCCaddress(cp,destaddr,pubkey2pk(pubkey)) != 0 ) - result.push_back(Pair("CCaddress",destaddr)); - } - if ( GetCCaddress(cp,destaddr,pubkey2pk(Mypubkey())) != 0 ) - result.push_back(Pair("myCCaddress",destaddr)); - return(result); -} - UniValue tokencreate(const UniValue& params, bool fHelp) { UniValue result(UniValue::VOBJ); std::string name,description,hex; uint64_t supply;