]> Git Repo - VerusCoin.git/blob - src/cc/dice.cpp
Prevent inputs of CC inputs
[VerusCoin.git] / src / cc / dice.cpp
1 /******************************************************************************
2  * Copyright © 2014-2018 The SuperNET Developers.                             *
3  *                                                                            *
4  * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at                  *
5  * the top-level directory of this distribution for the individual copyright  *
6  * holder information and the developer policies on copyright and licensing.  *
7  *                                                                            *
8  * Unless otherwise agreed in a custom licensing agreement, no part of the    *
9  * SuperNET software, including this file may be copied, modified, propagated *
10  * or distributed except according to the terms contained in the LICENSE file *
11  *                                                                            *
12  * Removal or modification of this copyright notice is prohibited.            *
13  *                                                                            *
14  ******************************************************************************/
15
16 #include "CCdice.h"
17 #include "../txmempool.h"
18
19 /*
20 */
21
22 // start of consensus code
23
24 uint64_t IsDicevout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
25 {
26     char destaddr[64];
27     if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
28     {
29         if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 )
30             return(tx.vout[v].nValue);
31     }
32     return(0);
33 }
34
35 bool DiceExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee)
36 {
37     static uint256 zerohash;
38     CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; uint64_t inputs=0,outputs=0,assetoshis;
39     numvins = tx.vin.size();
40     numvouts = tx.vout.size();
41     for (i=0; i<numvins; i++)
42     {
43         //fprintf(stderr,"vini.%d\n",i);
44         if ( (*cp->ismyvin)(tx.vin[i].scriptSig) != 0 )
45         {
46             //fprintf(stderr,"vini.%d check mempool\n",i);
47             if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 )
48                 return eval->Invalid("cant find vinTx");
49             else
50             {
51                 //fprintf(stderr,"vini.%d check hash and vout\n",i);
52                 if ( hashBlock == zerohash )
53                     return eval->Invalid("cant dice from mempool");
54                 if ( (assetoshis= IsDicevout(cp,vinTx,tx.vin[i].prevout.n)) != 0 )
55                     inputs += assetoshis;
56             }
57         }
58     }
59     for (i=0; i<numvouts; i++)
60     {
61         //fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts);
62         if ( (assetoshis= IsDicevout(cp,tx,i)) != 0 )
63             outputs += assetoshis;
64     }
65     if ( inputs != outputs+COIN+txfee )
66     {
67         fprintf(stderr,"inputs %llu vs outputs %llu\n",(long long)inputs,(long long)outputs);
68         return eval->Invalid("mismatched inputs != outputs + COIN + txfee");
69     }
70     else return(true);
71 }
72
73 bool DiceValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
74 {
75     int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; bool retval;
76     numvins = tx.vin.size();
77     numvouts = tx.vout.size();
78     preventCCvins = preventCCvouts = -1;
79     if ( numvouts < 1 )
80         return eval->Invalid("no vouts");
81     else
82     {
83         //fprintf(stderr,"check vins\n");
84         for (i=0; i<numvins; i++)
85         {
86             if ( IsCCInput(tx.vin[0].scriptSig) == 0 )
87             {
88                 fprintf(stderr,"diceget invalid vini\n");
89                 return eval->Invalid("illegal normal vini");
90             }
91         }
92         //fprintf(stderr,"check amounts\n");
93         if ( DiceExactAmounts(cp,eval,tx,1,10000) == false )
94         {
95             fprintf(stderr,"diceget invalid amount\n");
96             return false;
97         }
98         else
99         {
100             preventCCvouts = 1;
101             if ( IsDicevout(cp,tx,0) != 0 )
102             {
103                 preventCCvouts++;
104                 i = 1;
105             } else i = 0;
106             if ( tx.vout[i].nValue != COIN )
107                 return eval->Invalid("invalid dice output");
108             retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts);
109             if ( retval != 0 )
110                 fprintf(stderr,"diceget validated\n");
111             else fprintf(stderr,"diceget invalid\n");
112             return(retval);
113         }
114     }
115 }
116 // end of consensus code
117
118 // helper functions for rpc calls in rpcwallet.cpp
119
120 uint64_t AddDiceInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint64_t total,int32_t maxinputs)
121 {
122     char coinaddr[64]; uint64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t n = 0;
123     std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
124     GetCCaddress(cp,coinaddr,pk);
125     SetCCunspents(unspentOutputs,coinaddr);
126     for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
127     {
128         txid = it->first.txhash;
129         // prevent dup
130         if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
131         {
132             if ( (nValue= IsDicevout(cp,vintx,(int32_t)it->first.index)) > 0 )
133             {
134                 if ( total != 0 && maxinputs != 0 )
135                     mtx.vin.push_back(CTxIn(txid,(int32_t)it->first.index,CScript()));
136                 nValue = it->second.satoshis;
137                 totalinputs += nValue;
138                 n++;
139                 if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
140                     break;
141             }
142         }
143     }
144     return(totalinputs);
145 }
146
147 std::string DiceBet(uint64_t txfee,uint64_t amount,uint64_t odds)
148 {
149     CMutableTransaction mtx; CPubKey mypk,dicepk; CScript opret; uint64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
150     cp = CCinit(&C,EVAL_DICE);
151     if ( txfee == 0 )
152         txfee = 10000;
153     dicepk = GetUnspendable(cp,0);
154     mypk = pubkey2pk(Mypubkey());
155     if ( (inputs= AddDiceInputs(cp,mtx,dicepk,nValue+txfee,60)) > 0 )
156     {
157         if ( inputs > nValue )
158             CCchange = (inputs - nValue - txfee);
159         if ( CCchange != 0 )
160             mtx.vout.push_back(MakeCC1vout(EVAL_DICE,CCchange,dicepk));
161         mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
162         return(FinalizeCCTx(-1,cp,mtx,mypk,txfee,opret));
163     } else fprintf(stderr,"cant find dice inputs\n");
164     return(0);
165 }
166
167 std::string DiceFund(uint64_t txfee,uint64_t funds)
168 {
169     CMutableTransaction mtx; CPubKey mypk,dicepk; CScript opret; struct CCcontract_info *cp,C;
170     cp = CCinit(&C,EVAL_DICE);
171     if ( txfee == 0 )
172         txfee = 10000;
173     mypk = pubkey2pk(Mypubkey());
174     dicepk = GetUnspendable(cp,0);
175     if ( AddNormalinputs(mtx,mypk,funds+txfee,64) > 0 )
176     {
177         mtx.vout.push_back(MakeCC1vout(EVAL_DICE,funds,dicepk));
178         return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
179     }
180     return(0);
181 }
182
183
This page took 0.032834 seconds and 4 git commands to generate.