]> Git Repo - VerusCoin.git/blame - src/cc/prices.cpp
Merge branch 'dev' into jl777
[VerusCoin.git] / src / cc / prices.cpp
CommitLineData
c926780f 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 "CCPrices.h"
17
18/*
366625ca 19 Prices CC would best build on top of the oracles CC, ie. to combine payments for multiple oracles and to calculate a 51% protected price feed.
20
059f7e44 21 We need to assume there is an oracle for a specific price. In the event there are more than one provider, the majority need to be within correlation distance to update a pricepoint.
22
23 int64_t OraclePrice(int32_t height,uint256 reforacletxid,char *markeraddr,char *format);
24
25 Using the above function, a consensus price can be obtained for a datasource.
26
27 given an oracletxid, the marketaddr and format can be extracted to be used for future calls to OraclePrice. This allows to set a starting price and that in turn allows cash settled leveraged trading!
28
29 Funds work like with dice, ie. there is a Prices plan that traders bet against.
30
31 PricesOpen -> oracletxid start with 'L' price, leverage, amount
32 funds are locked into global CC address
33 it can be closed at anytime by the trader for cash settlement
34 the house account can close it if rekt
35
366625ca 36
c926780f 37*/
38
39// start of consensus code
40
41int64_t IsPricesvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
42{
43 char destaddr[64];
44 if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
45 {
46 if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 )
47 return(tx.vout[v].nValue);
48 }
49 return(0);
50}
51
52bool PricesExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee)
53{
54 static uint256 zerohash;
55 CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis;
56 numvins = tx.vin.size();
57 numvouts = tx.vout.size();
58 for (i=0; i<numvins; i++)
59 {
60 //fprintf(stderr,"vini.%d\n",i);
61 if ( (*cp->ismyvin)(tx.vin[i].scriptSig) != 0 )
62 {
63 //fprintf(stderr,"vini.%d check mempool\n",i);
64 if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 )
65 return eval->Invalid("cant find vinTx");
66 else
67 {
68 //fprintf(stderr,"vini.%d check hash and vout\n",i);
69 if ( hashBlock == zerohash )
70 return eval->Invalid("cant Prices from mempool");
71 if ( (assetoshis= IsPricesvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 )
72 inputs += assetoshis;
73 }
74 }
75 }
76 for (i=0; i<numvouts; i++)
77 {
78 //fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts);
79 if ( (assetoshis= IsPricesvout(cp,tx,i)) != 0 )
80 outputs += assetoshis;
81 }
82 if ( inputs != outputs+txfee )
83 {
84 fprintf(stderr,"inputs %llu vs outputs %llu\n",(long long)inputs,(long long)outputs);
85 return eval->Invalid("mismatched inputs != outputs + txfee");
86 }
87 else return(true);
88}
89
90bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
91{
92 int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numblocks; bool retval; uint256 txid; uint8_t hash[32]; char str[65],destaddr[64];
93 return(false);
94 std::vector<std::pair<CAddressIndexKey, CAmount> > txids;
95 numvins = tx.vin.size();
96 numvouts = tx.vout.size();
97 preventCCvins = preventCCvouts = -1;
98 if ( numvouts < 1 )
99 return eval->Invalid("no vouts");
100 else
101 {
102 for (i=0; i<numvins; i++)
103 {
104 if ( IsCCInput(tx.vin[0].scriptSig) == 0 )
105 {
106 return eval->Invalid("illegal normal vini");
107 }
108 }
109 //fprintf(stderr,"check amounts\n");
110 if ( PricesExactAmounts(cp,eval,tx,1,10000) == false )
111 {
112 fprintf(stderr,"Pricesget invalid amount\n");
113 return false;
114 }
115 else
116 {
117 txid = tx.GetHash();
118 memcpy(hash,&txid,sizeof(hash));
119 retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts);
120 if ( retval != 0 )
121 fprintf(stderr,"Pricesget validated\n");
122 else fprintf(stderr,"Pricesget invalid\n");
123 return(retval);
124 }
125 }
126}
127// end of consensus code
128
129// helper functions for rpc calls in rpcwallet.cpp
130
131int64_t AddPricesInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
132{
133 char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0;
134 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
135 GetCCaddress(cp,coinaddr,pk);
136 SetCCunspents(unspentOutputs,coinaddr);
137 for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
138 {
139 txid = it->first.txhash;
140 vout = (int32_t)it->first.index;
141 // no need to prevent dup
142 if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
143 {
144 if ( (nValue= IsPricesvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 )
145 {
146 if ( total != 0 && maxinputs != 0 )
147 mtx.vin.push_back(CTxIn(txid,vout,CScript()));
148 nValue = it->second.satoshis;
149 totalinputs += nValue;
150 n++;
151 if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
152 break;
153 }
154 }
155 }
156 return(totalinputs);
157}
158
059f7e44 159/*
160 UniValue PriceInfo(uint256 origtxid)
c926780f 161{
059f7e44 162 UniValue result(UniValue::VOBJ),a(UniValue::VARR),obj(UniValue::VOBJ);
163 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
164 CTransaction regtx,tx; std::string name,description,format; uint256 hashBlock,txid,oracletxid,batontxid; CPubKey markerpubkey,pk; struct CCcontract_info *cp,C; uint8_t buf33[33]; int64_t datafee,funding; char str[67],markeraddr[64],numstr[64],batonaddr[64]; std::vector <uint8_t> data;
165 cp = CCinit(&C,EVAL_ORACLES);
166 buf33[0] = 0x02;
167 endiancpy(&buf33[1],(uint8_t *)&origtxid,32);
168 markerpubkey = buf2pk(buf33);
169 Getscriptaddress(markeraddr,CScript() << ParseHex(HexStr(markerpubkey)) << OP_CHECKSIG);
170 if ( GetTransaction(origtxid,tx,hashBlock,false) != 0 )
c926780f 171 {
059f7e44 172 if ( tx.vout.size() > 0 && DecodeOraclesCreateOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,name,description,format) == 'C' )
c926780f 173 {
059f7e44 174 result.push_back(Pair("result","success"));
175 result.push_back(Pair("txid",uint256_str(str,origtxid)));
176 result.push_back(Pair("name",name));
177 result.push_back(Pair("description",description));
178 result.push_back(Pair("format",format));
179 result.push_back(Pair("marker",markeraddr));
180 SetCCunspents(unspentOutputs,markeraddr);
181 for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
c926780f 182 {
059f7e44 183 txid = it->first.txhash;
184 if ( GetTransaction(txid,regtx,hashBlock,false) != 0 )
c926780f 185 {
059f7e44 186 if ( regtx.vout.size() > 0 && DecodeOraclesOpRet(regtx.vout[regtx.vout.size()-1].scriptPubKey,oracletxid,pk,datafee) == 'R' && oracletxid == origtxid )
187 {
188 obj.push_back(Pair("provider",pubkey33_str(str,(uint8_t *)pk.begin())));
189 Getscriptaddress(batonaddr,regtx.vout[1].scriptPubKey);
190 batontxid = OracleBatonUtxo(10000,cp,oracletxid,batonaddr,pk,data);
191 obj.push_back(Pair("baton",batonaddr));
192 obj.push_back(Pair("batontxid",uint256_str(str,batontxid)));
193 funding = LifetimeOraclesFunds(cp,oracletxid,pk);
194 sprintf(numstr,"%.8f",(double)funding/COIN);
195 obj.push_back(Pair("lifetime",numstr));
196 funding = AddOracleInputs(cp,mtx,pk,0,0);
197 sprintf(numstr,"%.8f",(double)funding/COIN);
198 obj.push_back(Pair("funds",numstr));
199 sprintf(numstr,"%.8f",(double)datafee/COIN);
200 obj.push_back(Pair("datafee",numstr));
201 a.push_back(obj);
202 }
c926780f 203 }
c926780f 204 }
059f7e44 205 result.push_back(Pair("registered",a));
c926780f 206 }
059f7e44 207 }
208 return(result);
c926780f 209}
210
059f7e44 211UniValue PricesList()
c926780f 212{
059f7e44 213 UniValue result(UniValue::VARR); std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex; struct CCcontract_info *cp,C; uint256 txid,hashBlock; CTransaction createtx; std::string name,description,format; char str[65];
214 cp = CCinit(&C,EVAL_ORACLES);
215 SetCCtxids(addressIndex,cp->normaladdr);
216 for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++)
c926780f 217 {
059f7e44 218 txid = it->first.txhash;
219 if ( GetTransaction(txid,createtx,hashBlock,false) != 0 )
220 {
221 if ( createtx.vout.size() > 0 && DecodeOraclesCreateOpRet(createtx.vout[createtx.vout.size()-1].scriptPubKey,name,description,format) == 'C' )
222 {
223 result.push_back(uint256_str(str,txid));
224 }
225 }
c926780f 226 }
c926780f 227 return(result);
228}
059f7e44 229*/
This page took 0.058662 seconds and 4 git commands to generate.