Mining requires peers, ok for mainnet
[VerusCoin.git] / src / core_write.cpp
1 // Copyright (c) 2009-2014 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or https://www.opensource.org/licenses/mit-license.php .
4
5 #include "core_io.h"
6
7 #include "key_io.h"
8 #include "primitives/transaction.h"
9 #include "script/script.h"
10 #include "script/standard.h"
11 #include "serialize.h"
12 #include "streams.h"
13 #include <univalue.h>
14 #include "util.h"
15 #include "utilmoneystr.h"
16 #include "utilstrencodings.h"
17
18 #include "cc/eval.h"
19 #include "pbaas/reserves.h"
20 #include "pbaas/notarization.h"
21
22 #include <boost/assign/list_of.hpp>
23 #include <boost/foreach.hpp>
24
25 using namespace std;
26
27 string FormatScript(const CScript& script)
28 {
29     string ret;
30     CScript::const_iterator it = script.begin();
31     opcodetype op;
32     while (it != script.end()) {
33         CScript::const_iterator it2 = it;
34         vector<unsigned char> vch;
35         if (script.GetOp2(it, op, &vch)) {
36             if (op == OP_0) {
37                 ret += "0 ";
38                 continue;
39             } else if ((op >= OP_1 && op <= OP_16) || op == OP_1NEGATE) {
40                 ret += strprintf("%i ", op - OP_1NEGATE - 1);
41                 continue;
42             } else if (op >= OP_NOP && op <= OP_CHECKMULTISIGVERIFY) {
43                 string str(GetOpName(op));
44                 if (str.substr(0, 3) == string("OP_")) {
45                     ret += str.substr(3, string::npos) + " ";
46                     continue;
47                 }
48             }
49             if (vch.size() > 0) {
50                 ret += strprintf("0x%x 0x%x ", HexStr(it2, it - vch.size()), HexStr(it - vch.size(), it));
51             } else {
52                 ret += strprintf("0x%x", HexStr(it2, it));
53             }
54             continue;
55         }
56         ret += strprintf("0x%x ", HexStr(it2, script.end()));
57         break;
58     }
59     return ret.substr(0, ret.size() - 1);
60 }
61
62 const map<unsigned char, string> mapSigHashTypes =
63     boost::assign::map_list_of
64     (static_cast<unsigned char>(SIGHASH_ALL), string("ALL"))
65     (static_cast<unsigned char>(SIGHASH_ALL|SIGHASH_ANYONECANPAY), string("ALL|ANYONECANPAY"))
66     (static_cast<unsigned char>(SIGHASH_NONE), string("NONE"))
67     (static_cast<unsigned char>(SIGHASH_NONE|SIGHASH_ANYONECANPAY), string("NONE|ANYONECANPAY"))
68     (static_cast<unsigned char>(SIGHASH_SINGLE), string("SINGLE"))
69     (static_cast<unsigned char>(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY), string("SINGLE|ANYONECANPAY"))
70     ;
71
72 /**
73  * Create the assembly string representation of a CScript object.
74  * @param[in] script    CScript object to convert into the asm string representation.
75  * @param[in] fAttemptSighashDecode    Whether to attempt to decode sighash types on data within the script that matches the format
76  *                                     of a signature. Only pass true for scripts you believe could contain signatures. For example,
77  *                                     pass false, or omit the this argument (defaults to false), for scriptPubKeys.
78  */
79 string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode)
80 {
81     string str;
82     opcodetype opcode;
83     vector<unsigned char> vch;
84     CScript::const_iterator pc = script.begin();
85     while (pc < script.end()) {
86         if (!str.empty()) {
87             str += " ";
88         }
89         if (!script.GetOp(pc, opcode, vch)) {
90             str += "[error]";
91             return str;
92         }
93         if (0 <= opcode && opcode <= OP_PUSHDATA4) {
94             if (vch.size() <= static_cast<vector<unsigned char>::size_type>(4)) {
95                 str += strprintf("%d", CScriptNum(vch, false).getint());
96             } else {
97                 // the IsUnspendable check makes sure not to try to decode OP_RETURN data that may match the format of a signature
98                 if (fAttemptSighashDecode && !script.IsUnspendable()) {
99                     string strSigHashDecode;
100                     // goal: only attempt to decode a defined sighash type from data that looks like a signature within a scriptSig.
101                     // this won't decode correctly formatted public keys in Pubkey or Multisig scripts due to
102                     // the restrictions on the pubkey formats (see IsCompressedOrUncompressedPubKey) being incongruous with the
103                     // checks in CheckSignatureEncoding.
104                     if (CheckSignatureEncoding(vch, SCRIPT_VERIFY_STRICTENC, NULL)) {
105                         const unsigned char chSigHashType = vch.back();
106                         if (mapSigHashTypes.count(chSigHashType)) {
107                             strSigHashDecode = "[" + mapSigHashTypes.find(chSigHashType)->second + "]";
108                             vch.pop_back(); // remove the sighash type byte. it will be replaced by the decode.
109                         }
110                     }
111                     str += HexStr(vch) + strSigHashDecode;
112                 } else {
113                     str += HexStr(vch);
114                 }
115             }
116         } else {
117             str += GetOpName(opcode);
118         }
119     }
120     return str;
121 }
122
123 string EncodeHexTx(const CTransaction& tx)
124 {
125     CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
126     ssTx << tx;
127     return HexStr(ssTx.begin(), ssTx.end());
128 }
129
130 string EncodeHexBlk(const CBlock& tx)
131 {
132     CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
133     ssTx << tx;
134     return HexStr(ssTx.begin(), ssTx.end());
135 }
136
137 void ScriptPubKeyToUniv(const CScript& scriptPubKey,
138                         UniValue& out, bool fIncludeHex)
139 {
140     txnouttype type;
141     vector<CTxDestination> addresses;
142     int nRequired;
143
144     out.pushKV("asm", ScriptToAsmStr(scriptPubKey));
145     if (fIncludeHex)
146         out.pushKV("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end()));
147
148     if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) {
149         out.pushKV("type", GetTxnOutputType(type));
150         return;
151     }
152
153     out.pushKV("reqSigs", nRequired);
154     out.pushKV("type", GetTxnOutputType(type));
155
156     UniValue a(UniValue::VARR);
157     for (const CTxDestination& addr : addresses) {
158         a.push_back(EncodeDestination(addr));
159     }
160     out.pushKV("addresses", a);
161 }
162
163 UniValue ValueFromAmount(const CAmount& amount)
164 {
165     bool sign = amount < 0;
166     int64_t n_abs = (sign ? -amount : amount);
167     int64_t quotient = n_abs / COIN;
168     int64_t remainder = n_abs % COIN;
169     return UniValue(UniValue::VNUM,
170             strprintf("%s%d.%08d", sign ? "-" : "", quotient, remainder));
171 }
172
173 UniValue CNodeData::ToUniValue() const
174 {
175     UniValue obj(UniValue::VOBJ);
176     obj.push_back(Pair("networkaddress", networkAddress));
177     obj.push_back(Pair("nodeidentity", EncodeDestination(CIdentityID(nodeIdentity))));
178     return obj;
179 }
180
181 CCurrencyValueMap::CCurrencyValueMap(const UniValue &uni)
182 {
183     // must be an array of key:value, where key is currency ID encoded as i-address
184     if (uni.isObject())
185     {
186         const std::vector<std::string> &keys(uni.getKeys());
187         const std::vector<UniValue> &values(uni.getValues());
188         for (int i = 0; i < keys.size(); i++)
189         {
190             uint160 currencyID = GetDestinationID(DecodeDestination(keys[i]));
191             if (currencyID.IsNull())
192             {
193                 LogPrintf("Invalid JSON CurrencyValueMap\n");
194                 valueMap.clear();
195                 break;
196             }
197             if (valueMap.count(currencyID))
198             {
199                 LogPrintf("Duplicate currency in JSON CurrencyValueMap\n");
200                 valueMap.clear();
201                 break;
202             }
203
204             try
205             {
206                 valueMap[currencyID] = AmountFromValueNoErr(values[i]);
207             }
208             catch(const std::exception& e)
209             {
210                 std::cerr << e.what() << '\n';
211                 valueMap.clear();
212                 break;
213             }
214         }
215     }
216 }
217
218 UniValue CCurrencyValueMap::ToUniValue() const
219 {
220     UniValue retVal(UniValue::VOBJ);
221     for (auto &curValue : valueMap)
222     {
223         retVal.push_back(Pair(EncodeDestination(CIdentityID(curValue.first)), ValueFromAmount(curValue.second)));
224     }
225     return retVal;
226 }
227
228 uint160 CCurrencyDefinition::GetID(const std::string &Name, uint160 &Parent)
229 {
230     return CIdentity::GetID(Name, Parent);
231 }
232
233 uint160 CCurrencyDefinition::GetConditionID(int32_t condition) const
234 {
235     return CCrossChainRPCData::GetConditionID(name, condition);
236 }
237
238 UniValue CCurrencyState::ToUniValue() const
239 {
240     UniValue ret(UniValue::VOBJ);
241     ret.push_back(Pair("flags", (int32_t)flags));
242
243     if (IsValid() && IsFractional())
244     {
245         UniValue currencyArr(UniValue::VARR);
246         for (int i = 0; i < currencies.size(); i++)
247         {
248             UniValue currencyObj(UniValue::VOBJ);
249             currencyObj.push_back(Pair("currencyid", EncodeDestination(CIdentityID(currencies[i]))));
250             currencyObj.push_back(Pair("weight", ValueFromAmount(i < weights.size() ? weights[i] : 0)));
251             currencyObj.push_back(Pair("reserves", ValueFromAmount(i < reserves.size() ? reserves[i] : 0)));
252             currencyObj.push_back(Pair("priceinreserve", ValueFromAmount(PriceInReserve(i))));
253             currencyArr.push_back(currencyObj);
254         }
255         ret.push_back(Pair("reservecurrencies", currencyArr));
256     }
257     ret.push_back(Pair("initialsupply", ValueFromAmount(initialSupply)));
258     ret.push_back(Pair("emitted", ValueFromAmount(emitted)));
259     ret.push_back(Pair("supply", ValueFromAmount(supply)));
260     return ret;
261 }
262
263 CAmount CCurrencyState::PriceInReserve(int32_t reserveIndex, bool roundUp) const
264 {
265     if (reserveIndex >= reserves.size())
266     {
267         return 0;
268     }
269     if (!IsFractional())
270     {
271         return reserves[reserveIndex];
272     }
273
274     if (!supply || weights[reserveIndex] == 0)
275     {
276         return weights[reserveIndex];
277     }
278     arith_uint256 Supply(supply);
279     arith_uint256 Reserve(reserves[reserveIndex] ? reserves[reserveIndex] : SATOSHIDEN);
280     arith_uint256 Ratio(weights[reserveIndex]);
281     static arith_uint256 bigZero(0);
282     static arith_uint256 BigSatoshi(SATOSHIDEN);
283     static arith_uint256 BigSatoshiSquared = BigSatoshi * BigSatoshi;
284
285     if (roundUp)
286     {
287         arith_uint256 denominator = Supply * Ratio;
288         arith_uint256 numerator = Reserve * BigSatoshiSquared;
289         arith_uint256 bigAnswer = numerator / denominator;
290         int64_t remainder = (numerator - (bigAnswer * denominator)).GetLow64();
291         CAmount answer = bigAnswer.GetLow64();
292         if (remainder && (answer + 1) > 0)
293         {
294             answer++;
295         }
296         return answer;
297     }
298     else
299     {
300         return ((Reserve * BigSatoshiSquared) / (Supply * Ratio)).GetLow64();
301     }
302 }
303
304 cpp_dec_float_50 CCurrencyState::PriceInReserveDecFloat50(int32_t reserveIndex) const
305 {
306     cpp_dec_float_50 Supply(std::to_string((supply ? supply : 1)));
307     cpp_dec_float_50 Reserve(std::to_string(reserves[reserveIndex] ? reserves[reserveIndex] : SATOSHIDEN));
308     cpp_dec_float_50 Ratio(std::to_string(weights[reserveIndex]));
309     static cpp_dec_float_50 BigSatoshi(std::to_string(SATOSHIDEN));
310     static cpp_dec_float_50 BigSatoshiSquared = BigSatoshi * BigSatoshi;
311     return (Reserve * BigSatoshiSquared) / (Supply * Ratio);
312 }
313
314 std::vector<CAmount> CCurrencyState::PricesInReserve() const
315 {
316     std::vector<CAmount> retVal(currencies.size());
317     for (int i = 0; i < currencies.size(); i++)
318     {
319         retVal[i] = PriceInReserve(i);
320     }
321     return retVal;
322 }
323
324 CAmount CCurrencyState::ReserveToNativeRaw(CAmount reserveAmount, const cpp_dec_float_50 &price)
325 {
326     static cpp_dec_float_50 bigSatoshi(std::to_string(SATOSHIDEN));
327     static cpp_dec_float_50 bigZero(std::to_string(0));
328     cpp_dec_float_50 bigAmount(std::to_string(reserveAmount));
329
330     bigAmount = price != bigZero ? (bigAmount * bigSatoshi) / price : bigZero;
331     int64_t retVal;
332     if (to_int64(bigAmount, retVal))
333     {
334         return retVal;
335     }
336     return 0;
337 }
338
339 CAmount CCurrencyState::ReserveToNativeRaw(CAmount reserveAmount, CAmount exchangeRate)
340 {
341     return ReserveToNativeRaw(reserveAmount, cpp_dec_float_50(std::to_string(exchangeRate)));
342 }
343
344 CAmount CCurrencyState::ReserveToNativeRaw(const CCurrencyValueMap &reserveAmounts, const std::vector<CAmount> &exchangeRates) const
345 {
346     CAmount nativeOut = 0;
347     for (int i = 0; i < currencies.size(); i++)
348     {
349         auto it = reserveAmounts.valueMap.find(currencies[i]);
350         if (it != reserveAmounts.valueMap.end())
351         {
352             nativeOut += ReserveToNativeRaw(it->second, exchangeRates[i]);
353         }
354     }
355     return nativeOut;
356 }
357
358 CAmount CCurrencyState::ReserveToNativeRaw(const CCurrencyValueMap &reserveAmounts, 
359                                               const std::vector<uint160> &currencies, 
360                                               const std::vector<cpp_dec_float_50> &exchangeRates)
361 {
362     CAmount nativeOut = 0;
363     for (int i = 0; i < currencies.size(); i++)
364     {
365         auto it = reserveAmounts.valueMap.find(currencies[i]);
366         if (it != reserveAmounts.valueMap.end())
367         {
368             nativeOut += ReserveToNativeRaw(it->second, exchangeRates[i]);
369         }
370     }
371     return nativeOut;
372 }
373
374 CAmount CCurrencyState::ReserveToNativeRaw(const CCurrencyValueMap &reserveAmounts, 
375                                               const std::vector<uint160> &currencies, 
376                                               const std::vector<CAmount> &exchangeRates)
377 {
378     CAmount nativeOut = 0;
379     for (int i = 0; i < currencies.size(); i++)
380     {
381         auto it = reserveAmounts.valueMap.find(currencies[i]);
382         if (it != reserveAmounts.valueMap.end())
383         {
384             nativeOut += ReserveToNativeRaw(it->second, exchangeRates[i]);
385         }
386     }
387     return nativeOut;
388 }
389
390 CAmount CCurrencyState::ReserveToNative(CAmount reserveAmount, int32_t reserveIndex) const
391 {
392     return ReserveToNativeRaw(reserveAmount, PriceInReserveDecFloat50(reserveIndex));
393 }
394
395 CAmount CCurrencyState::NativeToReserveRaw(CAmount nativeAmount, const cpp_dec_float_50 &price)
396 {
397     static cpp_dec_float_50 bigSatoshi(std::to_string((SATOSHIDEN)));
398     cpp_dec_float_50 bigAmount(std::to_string(nativeAmount));
399     int64_t retVal;
400     cpp_dec_float_50 bigReserves = (bigAmount * price) / bigSatoshi;
401     if (to_int64(bigReserves, retVal))
402     {
403         return retVal;
404     }
405     return 0;
406 }
407
408 CAmount CCurrencyState::NativeToReserveRaw(CAmount nativeAmount, CAmount exchangeRate)
409 {
410     return NativeToReserveRaw(nativeAmount, cpp_dec_float_50(std::to_string(exchangeRate)));
411 }
412
413 CAmount CCurrencyState::NativeToReserve(CAmount nativeAmount, int32_t reserveIndex) const
414 {
415     return NativeToReserveRaw(nativeAmount, PriceInReserveDecFloat50(reserveIndex));
416 }
417
418 CCurrencyValueMap CCurrencyState::NativeToReserveRaw(const std::vector<CAmount> &nativeAmount, const std::vector<CAmount> &exchangeRates) const
419 {
420     static arith_uint256 bigSatoshi(SATOSHIDEN);
421     CCurrencyValueMap retVal;
422     for (int i = 0; i < currencies.size(); i++)
423     {
424         retVal.valueMap[currencies[i]] =  NativeToReserveRaw(nativeAmount[i], exchangeRates[i]);
425     }
426     return retVal;
427 }
428
429 CCurrencyValueMap CCurrencyState::NativeToReserveRaw(const std::vector<CAmount> &nativeAmount, const std::vector<cpp_dec_float_50> &exchangeRates) const
430 {
431     static arith_uint256 bigSatoshi(SATOSHIDEN);
432     CCurrencyValueMap retVal;
433     for (int i = 0; i < currencies.size(); i++)
434     {
435         retVal.valueMap[currencies[i]] =  NativeToReserveRaw(nativeAmount[i], exchangeRates[i]);
436     }
437     return retVal;
438 }
439
440 CAmount CCurrencyState::ReserveToNative(const CCurrencyValueMap &reserveAmounts) const
441 {
442     CAmount nativeOut = 0;
443     for (int i = 0; i < currencies.size(); i++)
444     {
445         auto it = reserveAmounts.valueMap.find(currencies[i]);
446         if (it != reserveAmounts.valueMap.end())
447         {
448             nativeOut += ReserveToNative(it->second, i);
449         }
450     }
451     return nativeOut;
452 }
453
454 template <typename INNERVECTOR>
455 UniValue ValueVectorsToUniValue(const std::vector<std::string> &rowNames,
456                                 const std::vector<std::string> &columnNames,
457                                 const std::vector<INNERVECTOR *> &vec,
458                                 bool columnVectors)
459 {
460     UniValue retVal(UniValue::VOBJ);
461     if (columnVectors)
462     {
463         for (int i = 0; i < rowNames.size(); i++)
464         {
465             UniValue row(UniValue::VOBJ);
466             for (int j = 0; j < columnNames.size(); j++)
467             {
468                 row.push_back(Pair(columnNames[j], ValueFromAmount((*(vec[j])).size() > i ? (*(vec[j]))[i] : 0)));
469             }
470             retVal.push_back(Pair(rowNames[i], row));
471         }
472     }
473     else
474     {
475         for (int i = 0; i < rowNames.size(); i++)
476         {
477             UniValue row(UniValue::VOBJ);
478             for (int j = 0; j < columnNames.size(); j++)
479             {
480                 row.push_back(Pair(columnNames[j], ValueFromAmount((*(vec[i])).size() > j ? (*(vec[i]))[j] : 0)));
481             }
482             retVal.push_back(Pair(rowNames[i], row));
483         }
484     }
485     return retVal;
486 }
487
488 UniValue CCoinbaseCurrencyState::ToUniValue() const
489 {
490     UniValue ret(UniValue::VOBJ);
491     ret = ((CCurrencyState *)this)->ToUniValue();
492     std::vector<std::string> rowNames;
493     for (int i = 0; i < currencies.size(); i++)
494     {
495         rowNames.push_back(EncodeDestination(CIdentityID(currencies[i])));
496     }
497     std::vector<std::string> columnNames({"reservein", "nativein", "reserveout", "lastconversionprice", "fees", "conversionfees"});
498     std::vector<const std::vector<CAmount> *> data = {&reserveIn, &nativeIn, &reserveOut, &conversionPrice, &fees, &conversionFees};
499
500     ret.push_back(Pair("currencies", ValueVectorsToUniValue(rowNames, columnNames, data, true)));
501     ret.push_back(Pair("nativefees", nativeFees));
502     ret.push_back(Pair("nativeconversionfees", nativeConversionFees));
503     return ret;
504 }
505
506 UniValue CPBaaSNotarization::ToUniValue() const
507 {
508     UniValue obj(UniValue::VOBJ);
509     obj.push_back(Pair("version", (int32_t)nVersion));
510     obj.push_back(Pair("currencyid", EncodeDestination(CIdentityID(currencyID))));
511     obj.push_back(Pair("notaryaddress", EncodeDestination(notaryDest)));
512     obj.push_back(Pair("notarizationheight", (int32_t)notarizationHeight));
513     obj.push_back(Pair("mmrroot", mmrRoot.GetHex()));
514     obj.push_back(Pair("notarizationprehash", notarizationPreHash.GetHex()));
515     obj.push_back(Pair("work", ((UintToArith256(compactPower) << 128) >> 128).ToString()));
516     obj.push_back(Pair("stake", (UintToArith256(compactPower) >> 128).ToString()));
517     obj.push_back(Pair("currencystate", currencyState.ToUniValue()));
518     obj.push_back(Pair("prevnotarization", prevNotarization.GetHex()));
519     obj.push_back(Pair("prevheight", prevHeight));
520     obj.push_back(Pair("crossnotarization", crossNotarization.GetHex()));
521     obj.push_back(Pair("crossheight", crossHeight));
522     UniValue nodesUni(UniValue::VARR);
523     for (auto node : nodes)
524     {
525         nodesUni.push_back(node.ToUniValue());
526     }
527     obj.push_back(Pair("nodes", nodesUni));
528     return obj;
529 }
530
531 UniValue CCurrencyDefinition::ToUniValue() const
532 {
533     UniValue obj(UniValue::VOBJ);
534
535     obj.push_back(Pair("name", name));
536     obj.push_back(Pair("version", (int64_t)nVersion));
537     obj.push_back(Pair("options", (int64_t)options));
538     obj.push_back(Pair("parent", EncodeDestination(CIdentityID(parent))));
539     obj.push_back(Pair("systemid", EncodeDestination(CIdentityID(systemID))));
540     obj.push_back(Pair("currencyid", EncodeDestination(CIdentityID(GetID()))));
541     obj.push_back(Pair("notarizationprotocol", (int)notarizationProtocol));
542     obj.push_back(Pair("proofprotocol", (int)proofProtocol));
543
544     obj.push_back(Pair("idregistrationprice", idRegistrationAmount));
545     obj.push_back(Pair("idreferrallevels", idReferralLevels));
546
547     // notaries are identities that perform specific functions for the currency's operation
548     // related to notarizing an external currency source, as well as proving imports
549     if (notaries.size())
550     {
551         UniValue notaryArr(UniValue::VARR);
552         for (auto &notary : notaries)
553         {
554             notaryArr.push_back(EncodeDestination(CIdentityID(notary)));
555         }
556         obj.push_back(Pair("notaries", notaryArr));
557     }
558     obj.push_back(Pair("minnotariesconfirm", minNotariesConfirm));
559
560     obj.push_back(Pair("billingperiod", billingPeriod));
561     obj.push_back(Pair("notarizationreward", notarizationReward));
562     obj.push_back(Pair("startblock", (int32_t)startBlock));
563     obj.push_back(Pair("endblock", (int32_t)endBlock));
564
565     // notaries are identities that perform specific functions for the currency's operation
566     // related to notarizing an external currency source, as well as proving imports
567     if (currencies.size())
568     {
569         UniValue currencyArr(UniValue::VARR);
570         for (auto &currency : currencies)
571         {
572             currencyArr.push_back(EncodeDestination(CIdentityID(currency)));
573         }
574         obj.push_back(Pair("currencies", currencyArr));
575     }
576
577     if (weights.size())
578     {
579         UniValue weightArr(UniValue::VARR);
580         for (auto &weight : weights)
581         {
582             weightArr.push_back(ValueFromAmount(weight));
583         }
584         obj.push_back(Pair("weights", weightArr));
585     }
586
587     if (conversions.size())
588     {
589         UniValue conversionArr(UniValue::VARR);
590         for (auto &conversion : conversions)
591         {
592             conversionArr.push_back(ValueFromAmount(conversion));
593         }
594         obj.push_back(Pair("conversions", conversionArr));
595     }
596
597     if (minPreconvert.size())
598     {
599         UniValue minPreconvertArr(UniValue::VARR);
600         for (auto &oneMin : minPreconvert)
601         {
602             minPreconvertArr.push_back(ValueFromAmount(oneMin));
603         }
604         obj.push_back(Pair("minpreconversion", minPreconvertArr));
605     }
606
607     if (maxPreconvert.size())
608     {
609         UniValue maxPreconvertArr(UniValue::VARR);
610         for (auto &oneMax : maxPreconvert)
611         {
612             maxPreconvertArr.push_back(ValueFromAmount(oneMax));
613         }
614         obj.push_back(Pair("maxpreconversion", maxPreconvertArr));
615     }
616
617     if (preLaunchDiscount)
618     {
619         obj.push_back(Pair("prelaunchdiscount", ValueFromAmount(preLaunchDiscount)));
620     }
621
622     if (preAllocation.size())
623     {
624         UniValue preAllocationArr(UniValue::VARR);
625         for (auto &onePreAllocation : preAllocation)
626         {
627             UniValue onePreAlloc(UniValue::VOBJ);
628             onePreAlloc.push_back(Pair(onePreAllocation.first.IsNull() ? "blockoneminer" : EncodeDestination(CIdentityID(onePreAllocation.first)), 
629                                        ValueFromAmount(onePreAllocation.second)));
630             preAllocationArr.push_back(onePreAlloc);
631         }
632         obj.push_back(Pair("preallocation", preAllocationArr));
633     }
634
635     if (contributions.size())
636     {
637         UniValue initialContributionArr(UniValue::VARR);
638         for (auto &oneCurContributions : contributions)
639         {
640             initialContributionArr.push_back(ValueFromAmount(oneCurContributions));
641         }
642         obj.push_back(Pair("initialcontributions", initialContributionArr));
643     }
644
645     if (preconverted.size())
646     {
647         UniValue preconversionArr(UniValue::VARR);
648         for (auto &onePreconversion : preconverted)
649         {
650             preconversionArr.push_back(ValueFromAmount(onePreconversion));
651         }
652         obj.push_back(Pair("preconversions", preconversionArr));
653     }
654
655     UniValue eraArr(UniValue::VARR);
656     for (int i = 0; i < rewards.size(); i++)
657     {
658         UniValue era(UniValue::VOBJ);
659         era.push_back(Pair("reward", rewards.size() > i ? rewards[i] : (int64_t)0));
660         era.push_back(Pair("decay", rewardsDecay.size() > i ? rewardsDecay[i] : (int64_t)0));
661         era.push_back(Pair("halving", halving.size() > i ? (int32_t)halving[i] : (int32_t)0));
662         era.push_back(Pair("eraend", eraEnd.size() > i ? (int32_t)eraEnd[i] : (int32_t)0));
663         eraArr.push_back(era);
664     }
665     obj.push_back(Pair("eras", eraArr));
666     return obj;
667 }
668
669 UniValue CTokenOutput::ToUniValue() const
670 {
671     UniValue ret(UniValue::VOBJ);
672     ret.push_back(Pair("version", (int64_t)nVersion));
673     ret.push_back(Pair("currencyid", currencyID.IsNull() ? "NULL" : EncodeDestination(CIdentityID(currencyID))));
674     ret.push_back(Pair("value", ValueFromAmount(nValue)));
675     return ret;
676 }
677
678 UniValue CReserveTransfer::ToUniValue() const
679 {
680     UniValue ret(((CTokenOutput *)this)->ToUniValue());
681     if (flags & PREALLOCATE)
682     {
683         ret.push_back(Pair("preallocation", true));
684     }
685     else if (flags & MINT_CURRENCY)
686     {
687         ret.push_back(Pair("mintedcurrency", true));
688     }
689     else
690     {
691         ret.push_back(Pair("convert", (bool)(flags & CONVERT)));
692         ret.push_back(Pair("preconvert", (bool)(flags & PRECONVERT)));
693         ret.push_back(Pair("feeoutput", (bool)(flags & FEE_OUTPUT)));
694         ret.push_back(Pair("sendback", (bool)(flags & SEND_BACK)));
695     }
696     ret.push_back(Pair("fees", ValueFromAmount(nFees)));
697     ret.push_back(Pair("destinationcurrencyid", EncodeDestination(CIdentityID(destCurrencyID))));
698     std::string destStr;
699     switch (destination.type)
700     {
701     case CTransferDestination::DEST_PKH:
702         destStr = EncodeDestination(CKeyID(uint160(destination.destination)));
703         break;
704
705     case CTransferDestination::DEST_SH:
706         destStr = EncodeDestination(CScriptID(uint160(destination.destination)));
707         break;
708
709     case CTransferDestination::DEST_ID:
710         destStr = EncodeDestination(CIdentityID(uint160(destination.destination)));
711         break;
712
713     case CTransferDestination::DEST_QUANTUM:
714         destStr = EncodeDestination(CQuantumID(uint160(destination.destination)));
715         break;
716
717     default:
718         destStr = HexStr(destination.destination);
719         break;
720     }
721     ret.push_back(Pair("destination", destStr));
722     return ret;
723 }
724
725 UniValue CReserveExchange::ToUniValue() const
726 {
727     UniValue ret(((CTokenOutput *)this)->ToUniValue());
728     ret.push_back(Pair("toreserve", (bool)(flags & TO_RESERVE)));
729     ret.push_back(Pair("tonative", !((bool)(flags & TO_RESERVE))));
730     ret.push_back(Pair("limitorder", (bool)(flags & LIMIT)));
731     if (flags & LIMIT)
732     {
733         ret.push_back(Pair("limitprice", ValueFromAmount(nLimit)));
734     }
735     ret.push_back(Pair("fillorkill", (bool)(flags & FILL_OR_KILL)));
736     if (flags & FILL_OR_KILL)
737     {
738         ret.push_back(Pair("validbeforeblock", (int32_t)nValidBefore));
739     }
740     ret.push_back(Pair("sendoutput", (bool)(flags & SEND_OUTPUT)));
741     return ret;
742 }
743
744 UniValue CCrossChainExport::ToUniValue() const
745 {
746     UniValue obj(UniValue::VOBJ);
747     obj.push_back(Pair("version", (int)nVersion));
748     obj.push_back(Pair("systemid", EncodeDestination(CIdentityID(systemID))));
749     obj.push_back(Pair("numinputs", numInputs));
750     obj.push_back(Pair("totalamounts", totalAmounts.ToUniValue()));
751     obj.push_back(Pair("totalfees", totalFees.ToUniValue()));
752     return obj;
753 }
754
755 UniValue CCrossChainImport::ToUniValue() const
756 {
757     UniValue obj(UniValue::VOBJ);
758     obj.push_back(Pair("version", (int)nVersion));
759     obj.push_back(Pair("systemid", EncodeDestination(CIdentityID(systemID))));
760     obj.push_back(Pair("valuein", importValue.ToUniValue()));
761     obj.push_back(Pair("tokensout", totalReserveOutMap.ToUniValue()));
762     return obj;
763 }
764
765 UniValue CPrincipal::ToUniValue() const
766 {
767     UniValue obj(UniValue::VOBJ);
768     obj.push_back(Pair("version", (int32_t)nVersion));
769     obj.push_back(Pair("flags", (int32_t)flags));
770
771     UniValue primaryAddressesUni(UniValue::VARR);
772     for (int i = 0; i < primaryAddresses.size(); i++)
773     {
774         primaryAddressesUni.push_back(EncodeDestination(primaryAddresses[i]));
775     }
776     obj.push_back(Pair("primaryaddresses", primaryAddressesUni));
777     obj.push_back(Pair("minimumsignatures", minSigs));
778     return obj;
779 }
780
781 UniValue CIdentity::ToUniValue() const
782 {
783     UniValue obj = ((CPrincipal *)this)->ToUniValue();
784
785     obj.push_back(Pair("identityaddress", EncodeDestination(CIdentityID(GetID()))));
786     obj.push_back(Pair("parent", EncodeDestination(CIdentityID(parent))));
787     obj.push_back(Pair("name", name));
788
789     UniValue hashes(UniValue::VOBJ);
790     for (auto &entry : contentMap)
791     {
792         hashes.push_back(Pair(entry.first.GetHex(), entry.second.GetHex()));
793     }
794     obj.push_back(Pair("contentmap", hashes));
795
796     obj.push_back(Pair("revocationauthority", EncodeDestination(CTxDestination(CIdentityID(revocationAuthority)))));
797     obj.push_back(Pair("recoveryauthority", EncodeDestination(CTxDestination(CIdentityID(recoveryAuthority)))));
798     if (privateAddresses.size())
799     {
800         obj.push_back(Pair("privateaddress", EncodePaymentAddress(privateAddresses[0])));
801     }
802     return obj;
803 }
804
805 UniValue CMMRProof::ToUniValue() const
806 {
807     UniValue retObj(UniValue::VOBJ);
808     for (auto &proof : proofSequence)
809     {
810         UniValue branchArray(UniValue::VARR);
811         switch (proof->branchType)
812         {
813             case CMerkleBranchBase::BRANCH_BTC:
814             {
815                 CBTCMerkleBranch &branch = *(CBTCMerkleBranch *)(proof);
816                 retObj.push_back(Pair("branchtype", "BTC"));
817                 retObj.push_back(Pair("index", (int64_t)(branch.nIndex)));
818                 for (auto &oneHash : branch.branch)
819                 {
820                     branchArray.push_back(oneHash.GetHex());
821                 }
822                 retObj.push_back(Pair("hashes", branchArray));
823                 break;
824             }
825             case CMerkleBranchBase::BRANCH_MMRBLAKE_NODE:
826             {
827                 CMMRNodeBranch &branch = *(CMMRNodeBranch *)(proof);
828                 retObj.push_back(Pair("branchtype", "MMRBLAKENODE"));
829                 retObj.push_back(Pair("index", (int64_t)(branch.nIndex)));
830                 retObj.push_back(Pair("mmvsize", (int64_t)(branch.nSize)));
831                 for (auto &oneHash : branch.branch)
832                 {
833                     branchArray.push_back(oneHash.GetHex());
834                 }
835                 retObj.push_back(Pair("hashes", branchArray));
836                 break;
837             }
838             case CMerkleBranchBase::BRANCH_MMRBLAKE_POWERNODE:
839             {
840                 CMMRPowerNodeBranch &branch = *(CMMRPowerNodeBranch *)(proof);
841                 retObj.push_back(Pair("branchtype", "MMRBLAKEPOWERNODE"));
842                 retObj.push_back(Pair("index", (int64_t)(branch.nIndex)));
843                 retObj.push_back(Pair("mmvsize", (int64_t)(branch.nSize)));
844                 for (auto &oneHash : branch.branch)
845                 {
846                     branchArray.push_back(oneHash.GetHex());
847                 }
848                 retObj.push_back(Pair("hashes", branchArray));
849                 break;
850             }
851         };
852     }
853     return retObj;
854 }
855
856 void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex, bool fIncludeAsm)
857 {
858     txnouttype type;
859     vector<CTxDestination> addresses;
860
861     // needs to be an object
862     if (!out.isObject())
863     {
864         out = UniValue(UniValue::VOBJ);
865     }
866
867     int nRequired;
868     ExtractDestinations(scriptPubKey, type, addresses, nRequired);
869     out.push_back(Pair("type", GetTxnOutputType(type)));
870
871     COptCCParams p;
872     if (scriptPubKey.IsPayToCryptoCondition(p) && p.version >= COptCCParams::VERSION_V2)
873     {
874         switch(p.evalCode)
875         {
876             case EVAL_CURRENCY_DEFINITION:
877             {
878                 CCurrencyDefinition definition;
879
880                 if (p.vData.size() && (definition = CCurrencyDefinition(p.vData[0])).IsValid())
881                 {
882                     out.push_back(Pair("currencydefinition", definition.ToUniValue()));
883                 }
884                 else
885                 {
886                     out.push_back(Pair("currencydefinition", "invalid"));
887                 }
888                 break;
889             }
890
891             case EVAL_SERVICEREWARD:
892             {
893                 CServiceReward reward;
894
895                 if (p.vData.size() && (reward = CServiceReward(p.vData[0])).IsValid())
896                 {
897                     out.push_back(Pair("pbaasServiceReward", reward.ToUniValue()));
898                 }
899                 else
900                 {
901                     out.push_back(Pair("pbaasServiceReward", "invalid"));
902                 }
903                 break;
904             }
905
906             case EVAL_EARNEDNOTARIZATION:
907             case EVAL_ACCEPTEDNOTARIZATION:
908             {
909                 CPBaaSNotarization notarization;
910
911                 if (p.vData.size() && (notarization = CPBaaSNotarization(p.vData[0])).IsValid())
912                 {
913                     out.push_back(Pair("pbaasNotarization", notarization.ToUniValue()));
914                 }
915                 else
916                 {
917                     out.push_back(Pair("pbaasNotarization", "invalid"));
918                 }
919                 break;
920             }
921
922             case EVAL_FINALIZE_NOTARIZATION:
923             {
924                 CTransactionFinalization finalization;
925
926                 if (p.vData.size())
927                 {
928                     finalization = CTransactionFinalization(p.vData[0]);
929                     out.push_back(Pair("finalizeNotarization", finalization.ToUniValue()));
930                 }
931                 break;
932             }
933
934             case EVAL_CURRENCYSTATE:
935             {
936                 CCoinbaseCurrencyState cbcs;
937
938                 if (p.vData.size() && (cbcs = CCoinbaseCurrencyState(p.vData[0])).IsValid())
939                 {
940                     out.push_back(Pair("currencystate", cbcs.ToUniValue()));
941                 }
942                 else
943                 {
944                     out.push_back(Pair("currencystate", "invalid"));
945                 }
946                 break;
947             }
948
949             case EVAL_RESERVE_TRANSFER:
950             {
951                 CReserveTransfer rt;
952
953                 if (p.vData.size() && (rt = CReserveTransfer(p.vData[0])).IsValid())
954                 {
955                     out.push_back(Pair("reservetransfer", rt.ToUniValue()));
956                 }
957                 else
958                 {
959                     out.push_back(Pair("reservetransfer", "invalid"));
960                 }
961                 break;
962             }
963
964             case EVAL_RESERVE_OUTPUT:
965             {
966                 CTokenOutput ro;
967
968                 if (p.vData.size() && (ro = CTokenOutput(p.vData[0])).IsValid())
969                 {
970                     out.push_back(Pair("reserveoutput", ro.ToUniValue()));
971                 }
972                 else
973                 {
974                     out.push_back(Pair("reserveoutput", "invalid"));
975                 }
976                 break;
977             }
978
979             case EVAL_RESERVE_EXCHANGE:
980             {
981                 CReserveExchange rex;
982
983                 if (p.vData.size() && (rex = CReserveExchange(p.vData[0])).IsValid())
984                 {
985                     out.push_back(Pair("reserveexchange", rex.ToUniValue()));
986                 }
987                 else
988                 {
989                     out.push_back(Pair("reserveexchange", "invalid"));
990                 }
991                 break;
992             }
993
994             case EVAL_RESERVE_DEPOSIT:
995             {
996                 CTokenOutput ro;
997
998                 if (p.vData.size() && (ro = CTokenOutput(p.vData[0])).IsValid())
999                 {
1000                     out.push_back(Pair("reservedeposit", ro.ToUniValue()));
1001                 }
1002                 else
1003                 {
1004                     out.push_back(Pair("reservedeposit", "invalid"));
1005                 }
1006                 break;
1007             }
1008
1009             case EVAL_CROSSCHAIN_EXPORT:
1010             {
1011                 CCrossChainExport ccx;
1012
1013                 if (p.vData.size() && (ccx = CCrossChainExport(p.vData[0])).IsValid())
1014                 {
1015                     out.push_back(Pair("crosschainexport", ccx.ToUniValue()));
1016                 }
1017                 else
1018                 {
1019                     out.push_back(Pair("crosschainexport", "invalid"));
1020                 }
1021                 break;
1022             }
1023
1024             case EVAL_CROSSCHAIN_IMPORT:
1025             {
1026                 CCrossChainImport cci;
1027
1028                 if (p.vData.size() && (cci = CCrossChainImport(p.vData[0])).IsValid())
1029                 {
1030                     out.push_back(Pair("crosschainimport", cci.ToUniValue()));
1031                 }
1032                 else
1033                 {
1034                     out.push_back(Pair("crosschainimport", "invalid"));
1035                 }
1036                 break;
1037             }
1038
1039             case EVAL_IDENTITY_PRIMARY:
1040             {
1041                 CIdentity identity;
1042
1043                 if (p.vData.size() && (identity = CIdentity(p.vData[0])).IsValid())
1044                 {
1045                     out.push_back(Pair("identityprimary", identity.ToUniValue()));
1046                 }
1047                 else
1048                 {
1049                     out.push_back(Pair("identityprimary", "invalid"));
1050                 }
1051                 break;
1052             }
1053
1054             case EVAL_IDENTITY_REVOKE:
1055                 out.push_back(Pair("identityrevoke", ""));
1056                 break;
1057
1058             case EVAL_IDENTITY_RECOVER:
1059                 out.push_back(Pair("identityrecover", ""));
1060                 break;
1061
1062             case EVAL_IDENTITY_COMMITMENT:
1063                 out.push_back(Pair("identitycommitment", ""));
1064                 break;
1065
1066             case EVAL_IDENTITY_RESERVATION:
1067                 out.push_back(Pair("identityreservation", ""));
1068                 break;
1069
1070             case EVAL_STAKEGUARD:
1071                 out.push_back(Pair("stakeguard", ""));
1072                 break;
1073
1074             case EVAL_FINALIZE_EXPORT:
1075             {
1076                 CTransactionFinalization finalization;
1077
1078                 if (p.vData.size())
1079                 {
1080                     finalization = CTransactionFinalization(p.vData[0]);
1081                     out.push_back(Pair("finalizeexport", finalization.ToUniValue()));
1082                 }
1083                 break;
1084             }
1085
1086             default:
1087                 out.push_back(Pair("unknown", ""));
1088         }
1089     }
1090
1091     if (addresses.size())
1092     {
1093         out.push_back(Pair("reqSigs", nRequired));
1094
1095         UniValue a(UniValue::VARR);
1096         for (const CTxDestination& addr : addresses) {
1097             a.push_back(EncodeDestination(addr));
1098         }
1099         out.push_back(Pair("addresses", a));
1100     }
1101
1102     if (fIncludeAsm)
1103     {
1104         out.push_back(Pair("asm", ScriptToAsmStr(scriptPubKey)));
1105     }
1106
1107     if (fIncludeHex)
1108     {
1109         out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
1110     }
1111 }
1112
1113 void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry)
1114 {
1115     entry.pushKV("txid", tx.GetHash().GetHex());
1116     entry.pushKV("version", tx.nVersion);
1117     entry.pushKV("locktime", (int64_t)tx.nLockTime);
1118
1119     UniValue vin(UniValue::VARR);
1120     BOOST_FOREACH(const CTxIn& txin, tx.vin) {
1121         UniValue in(UniValue::VOBJ);
1122         if (tx.IsCoinBase())
1123             in.pushKV("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
1124         else {
1125             in.pushKV("txid", txin.prevout.hash.GetHex());
1126             in.pushKV("vout", (int64_t)txin.prevout.n);
1127             UniValue o(UniValue::VOBJ);
1128             o.pushKV("asm", ScriptToAsmStr(txin.scriptSig, true));
1129             o.pushKV("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
1130             in.pushKV("scriptSig", o);
1131         }
1132         in.pushKV("sequence", (int64_t)txin.nSequence);
1133         vin.push_back(in);
1134     }
1135     entry.pushKV("vin", vin);
1136
1137     UniValue vout(UniValue::VARR);
1138     for (unsigned int i = 0; i < tx.vout.size(); i++) {
1139         const CTxOut& txout = tx.vout[i];
1140
1141         UniValue out(UniValue::VOBJ);
1142
1143         UniValue outValue(UniValue::VNUM, FormatMoney(txout.nValue));
1144         out.pushKV("value", outValue);
1145         out.pushKV("n", (int64_t)i);
1146
1147         UniValue o(UniValue::VOBJ);
1148         ScriptPubKeyToUniv(txout.scriptPubKey, o, true, false);
1149         out.pushKV("scriptPubKey", o);
1150         vout.push_back(out);
1151     }
1152     entry.pushKV("vout", vout);
1153
1154     if (!hashBlock.IsNull())
1155         entry.pushKV("blockhash", hashBlock.GetHex());
1156
1157     entry.pushKV("hex", EncodeHexTx(tx)); // the hex-encoded transaction. used the name "hex" to be consistent with the verbose output of "getrawtransaction".
1158 }
This page took 0.087961 seconds and 4 git commands to generate.