]> Git Repo - VerusCoin.git/blame - src/core_write.cpp
Mining requires peers, ok for mainnet
[VerusCoin.git] / src / core_write.cpp
CommitLineData
f914f1a7 1// Copyright (c) 2009-2014 The Bitcoin Core developers
78253fcb 2// Distributed under the MIT software license, see the accompanying
bc909a7a 3// file COPYING or https://www.opensource.org/licenses/mit-license.php .
ae775b5b
JG
4
5#include "core_io.h"
611116d4 6
3d31e09c 7#include "key_io.h"
d2270111 8#include "primitives/transaction.h"
c4408a6c 9#include "script/script.h"
10#include "script/standard.h"
ae775b5b 11#include "serialize.h"
fa736190 12#include "streams.h"
a10a6e2a 13#include <univalue.h>
ae775b5b 14#include "util.h"
ad49c256 15#include "utilmoneystr.h"
85c579e3 16#include "utilstrencodings.h"
ae775b5b 17
56a7b665 18#include "cc/eval.h"
19#include "pbaas/reserves.h"
20#include "pbaas/notarization.h"
21
690d38f0 22#include <boost/assign/list_of.hpp>
53efb09e 23#include <boost/foreach.hpp>
24
ae775b5b
JG
25using namespace std;
26
8138cbea
PW
27string 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
690d38f0 62const 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 */
79string 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
ae775b5b
JG
123string EncodeHexTx(const CTransaction& tx)
124{
125 CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
126 ssTx << tx;
127 return HexStr(ssTx.begin(), ssTx.end());
128}
129
f8f61a6d 130string EncodeHexBlk(const CBlock& tx)
131{
132 CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
133 ssTx << tx;
134 return HexStr(ssTx.begin(), ssTx.end());
135}
136
cbe39a38
JG
137void ScriptPubKeyToUniv(const CScript& scriptPubKey,
138 UniValue& out, bool fIncludeHex)
139{
140 txnouttype type;
141 vector<CTxDestination> addresses;
142 int nRequired;
143
690d38f0 144 out.pushKV("asm", ScriptToAsmStr(scriptPubKey));
cbe39a38
JG
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);
07444da1
PW
157 for (const CTxDestination& addr : addresses) {
158 a.push_back(EncodeDestination(addr));
159 }
cbe39a38
JG
160 out.pushKV("addresses", a);
161}
162
56a7b665 163UniValue 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
173UniValue 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
0122934f 181CCurrencyValueMap::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
56a7b665 218UniValue CCurrencyValueMap::ToUniValue() const
219{
0122934f 220 UniValue retVal(UniValue::VOBJ);
56a7b665 221 for (auto &curValue : valueMap)
222 {
0122934f 223 retVal.push_back(Pair(EncodeDestination(CIdentityID(curValue.first)), ValueFromAmount(curValue.second)));
56a7b665 224 }
225 return retVal;
226}
227
228uint160 CCurrencyDefinition::GetID(const std::string &Name, uint160 &Parent)
229{
230 return CIdentity::GetID(Name, Parent);
231}
232
233uint160 CCurrencyDefinition::GetConditionID(int32_t condition) const
234{
235 return CCrossChainRPCData::GetConditionID(name, condition);
236}
237
c8c677c9 238UniValue CCurrencyState::ToUniValue() const
56a7b665 239{
240 UniValue ret(UniValue::VOBJ);
241 ret.push_back(Pair("flags", (int32_t)flags));
242
4005d836 243 if (IsValid() && IsFractional())
56a7b665 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
19ce962e 263CAmount CCurrencyState::PriceInReserve(int32_t reserveIndex, bool roundUp) const
d07e4ab8 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]);
19ce962e 281 static arith_uint256 bigZero(0);
d07e4ab8 282 static arith_uint256 BigSatoshi(SATOSHIDEN);
283 static arith_uint256 BigSatoshiSquared = BigSatoshi * BigSatoshi;
284
19ce962e 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 }
d07e4ab8 302}
303
304cpp_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
314std::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
324CAmount 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
339CAmount CCurrencyState::ReserveToNativeRaw(CAmount reserveAmount, CAmount exchangeRate)
340{
341 return ReserveToNativeRaw(reserveAmount, cpp_dec_float_50(std::to_string(exchangeRate)));
342}
343
344CAmount 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
358CAmount 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
374CAmount 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
390CAmount CCurrencyState::ReserveToNative(CAmount reserveAmount, int32_t reserveIndex) const
391{
392 return ReserveToNativeRaw(reserveAmount, PriceInReserveDecFloat50(reserveIndex));
393}
394
395CAmount 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
408CAmount CCurrencyState::NativeToReserveRaw(CAmount nativeAmount, CAmount exchangeRate)
409{
410 return NativeToReserveRaw(nativeAmount, cpp_dec_float_50(std::to_string(exchangeRate)));
411}
412
413CAmount CCurrencyState::NativeToReserve(CAmount nativeAmount, int32_t reserveIndex) const
414{
415 return NativeToReserveRaw(nativeAmount, PriceInReserveDecFloat50(reserveIndex));
416}
417
418CCurrencyValueMap 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
429CCurrencyValueMap 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
440CAmount 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
56a7b665 454template <typename INNERVECTOR>
455UniValue 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
488UniValue CCoinbaseCurrencyState::ToUniValue() const
489{
490 UniValue ret(UniValue::VOBJ);
c8c677c9 491 ret = ((CCurrencyState *)this)->ToUniValue();
56a7b665 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
506UniValue CPBaaSNotarization::ToUniValue() const
507{
508 UniValue obj(UniValue::VOBJ);
509 obj.push_back(Pair("version", (int32_t)nVersion));
cc3d5cb5 510 obj.push_back(Pair("currencyid", EncodeDestination(CIdentityID(currencyID))));
56a7b665 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
531UniValue 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
1fb6db72 617 if (preLaunchDiscount)
56a7b665 618 {
68ddda5e 619 obj.push_back(Pair("prelaunchdiscount", ValueFromAmount(preLaunchDiscount)));
56a7b665 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
669UniValue CTokenOutput::ToUniValue() const
670{
671 UniValue ret(UniValue::VOBJ);
672 ret.push_back(Pair("version", (int64_t)nVersion));
5781675d 673 ret.push_back(Pair("currencyid", currencyID.IsNull() ? "NULL" : EncodeDestination(CIdentityID(currencyID))));
56a7b665 674 ret.push_back(Pair("value", ValueFromAmount(nValue)));
675 return ret;
676}
677
678UniValue CReserveTransfer::ToUniValue() const
679{
680 UniValue ret(((CTokenOutput *)this)->ToUniValue());
15197dca 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 }
56a7b665 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
725UniValue 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
744UniValue 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
755UniValue 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()));
7beb1c0b 761 obj.push_back(Pair("tokensout", totalReserveOutMap.ToUniValue()));
56a7b665 762 return obj;
763}
764
765UniValue 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
781UniValue 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
e8b83707 805UniValue 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
56a7b665 856void 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 {
7beb1c0b 882 out.push_back(Pair("currencydefinition", definition.ToUniValue()));
56a7b665 883 }
884 else
885 {
7beb1c0b 886 out.push_back(Pair("currencydefinition", "invalid"));
56a7b665 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
09b977c6 922 case EVAL_FINALIZE_NOTARIZATION:
56a7b665 923 {
09b977c6 924 CTransactionFinalization finalization;
56a7b665 925
926 if (p.vData.size())
927 {
09b977c6 928 finalization = CTransactionFinalization(p.vData[0]);
929 out.push_back(Pair("finalizeNotarization", finalization.ToUniValue()));
56a7b665 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
09b977c6 1074 case EVAL_FINALIZE_EXPORT:
56a7b665 1075 {
09b977c6 1076 CTransactionFinalization finalization;
56a7b665 1077
09b977c6 1078 if (p.vData.size())
56a7b665 1079 {
09b977c6 1080 finalization = CTransactionFinalization(p.vData[0]);
05cef42a 1081 out.push_back(Pair("finalizeexport", finalization.ToUniValue()));
56a7b665 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
cbe39a38
JG
1113void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry)
1114{
805344dc 1115 entry.pushKV("txid", tx.GetHash().GetHex());
cbe39a38
JG
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);
690d38f0 1128 o.pushKV("asm", ScriptToAsmStr(txin.scriptSig, true));
cbe39a38
JG
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);
56a7b665 1148 ScriptPubKeyToUniv(txout.scriptPubKey, o, true, false);
cbe39a38
JG
1149 out.pushKV("scriptPubKey", o);
1150 vout.push_back(out);
1151 }
1152 entry.pushKV("vout", vout);
1153
4f152496 1154 if (!hashBlock.IsNull())
cbe39a38 1155 entry.pushKV("blockhash", hashBlock.GetHex());
84877904 1156
1157 entry.pushKV("hex", EncodeHexTx(tx)); // the hex-encoded transaction. used the name "hex" to be consistent with the verbose output of "getrawtransaction".
cbe39a38 1158}
This page took 0.349022 seconds and 4 git commands to generate.