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 .
8 #include "primitives/transaction.h"
9 #include "script/script.h"
10 #include "script/standard.h"
11 #include "serialize.h"
15 #include "utilmoneystr.h"
16 #include "utilstrencodings.h"
19 #include "pbaas/reserves.h"
20 #include "pbaas/notarization.h"
22 #include <boost/assign/list_of.hpp>
23 #include <boost/foreach.hpp>
27 string FormatScript(const CScript& script)
30 CScript::const_iterator it = script.begin();
32 while (it != script.end()) {
33 CScript::const_iterator it2 = it;
34 vector<unsigned char> vch;
35 if (script.GetOp2(it, op, &vch)) {
39 } else if ((op >= OP_1 && op <= OP_16) || op == OP_1NEGATE) {
40 ret += strprintf("%i ", op - OP_1NEGATE - 1);
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) + " ";
50 ret += strprintf("0x%x 0x%x ", HexStr(it2, it - vch.size()), HexStr(it - vch.size(), it));
52 ret += strprintf("0x%x", HexStr(it2, it));
56 ret += strprintf("0x%x ", HexStr(it2, script.end()));
59 return ret.substr(0, ret.size() - 1);
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"))
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.
79 string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode)
83 vector<unsigned char> vch;
84 CScript::const_iterator pc = script.begin();
85 while (pc < script.end()) {
89 if (!script.GetOp(pc, opcode, vch)) {
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());
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.
111 str += HexStr(vch) + strSigHashDecode;
117 str += GetOpName(opcode);
123 string EncodeHexTx(const CTransaction& tx)
125 CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
127 return HexStr(ssTx.begin(), ssTx.end());
130 string EncodeHexBlk(const CBlock& tx)
132 CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
134 return HexStr(ssTx.begin(), ssTx.end());
137 void ScriptPubKeyToUniv(const CScript& scriptPubKey,
138 UniValue& out, bool fIncludeHex)
141 vector<CTxDestination> addresses;
144 out.pushKV("asm", ScriptToAsmStr(scriptPubKey));
146 out.pushKV("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end()));
148 if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) {
149 out.pushKV("type", GetTxnOutputType(type));
153 out.pushKV("reqSigs", nRequired);
154 out.pushKV("type", GetTxnOutputType(type));
156 UniValue a(UniValue::VARR);
157 for (const CTxDestination& addr : addresses) {
158 a.push_back(EncodeDestination(addr));
160 out.pushKV("addresses", a);
163 UniValue ValueFromAmount(const CAmount& amount)
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));
173 UniValue CNodeData::ToUniValue() const
175 UniValue obj(UniValue::VOBJ);
176 obj.push_back(Pair("networkaddress", networkAddress));
177 obj.push_back(Pair("nodeidentity", EncodeDestination(CIdentityID(nodeIdentity))));
181 CCurrencyValueMap::CCurrencyValueMap(const UniValue &uni)
183 // must be an array of key:value, where key is currency ID encoded as i-address
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++)
190 uint160 currencyID = GetDestinationID(DecodeDestination(keys[i]));
191 if (currencyID.IsNull())
193 LogPrintf("Invalid JSON CurrencyValueMap\n");
197 if (valueMap.count(currencyID))
199 LogPrintf("Duplicate currency in JSON CurrencyValueMap\n");
206 valueMap[currencyID] = AmountFromValueNoErr(values[i]);
208 catch(const std::exception& e)
210 std::cerr << e.what() << '\n';
218 UniValue CCurrencyValueMap::ToUniValue() const
220 UniValue retVal(UniValue::VOBJ);
221 for (auto &curValue : valueMap)
223 retVal.push_back(Pair(EncodeDestination(CIdentityID(curValue.first)), ValueFromAmount(curValue.second)));
228 uint160 CCurrencyDefinition::GetID(const std::string &Name, uint160 &Parent)
230 return CIdentity::GetID(Name, Parent);
233 uint160 CCurrencyDefinition::GetConditionID(int32_t condition) const
235 return CCrossChainRPCData::GetConditionID(name, condition);
238 UniValue CCurrencyState::ToUniValue() const
240 UniValue ret(UniValue::VOBJ);
241 ret.push_back(Pair("flags", (int32_t)flags));
243 if (IsValid() && IsFractional())
245 UniValue currencyArr(UniValue::VARR);
246 for (int i = 0; i < currencies.size(); i++)
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);
255 ret.push_back(Pair("reservecurrencies", currencyArr));
257 ret.push_back(Pair("initialsupply", ValueFromAmount(initialSupply)));
258 ret.push_back(Pair("emitted", ValueFromAmount(emitted)));
259 ret.push_back(Pair("supply", ValueFromAmount(supply)));
263 CAmount CCurrencyState::PriceInReserve(int32_t reserveIndex, bool roundUp) const
265 if (reserveIndex >= reserves.size())
271 return reserves[reserveIndex];
274 if (!supply || weights[reserveIndex] == 0)
276 return weights[reserveIndex];
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;
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)
300 return ((Reserve * BigSatoshiSquared) / (Supply * Ratio)).GetLow64();
304 cpp_dec_float_50 CCurrencyState::PriceInReserveDecFloat50(int32_t reserveIndex) const
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);
314 std::vector<CAmount> CCurrencyState::PricesInReserve() const
316 std::vector<CAmount> retVal(currencies.size());
317 for (int i = 0; i < currencies.size(); i++)
319 retVal[i] = PriceInReserve(i);
324 CAmount CCurrencyState::ReserveToNativeRaw(CAmount reserveAmount, const cpp_dec_float_50 &price)
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));
330 bigAmount = price != bigZero ? (bigAmount * bigSatoshi) / price : bigZero;
332 if (to_int64(bigAmount, retVal))
339 CAmount CCurrencyState::ReserveToNativeRaw(CAmount reserveAmount, CAmount exchangeRate)
341 return ReserveToNativeRaw(reserveAmount, cpp_dec_float_50(std::to_string(exchangeRate)));
344 CAmount CCurrencyState::ReserveToNativeRaw(const CCurrencyValueMap &reserveAmounts, const std::vector<CAmount> &exchangeRates) const
346 CAmount nativeOut = 0;
347 for (int i = 0; i < currencies.size(); i++)
349 auto it = reserveAmounts.valueMap.find(currencies[i]);
350 if (it != reserveAmounts.valueMap.end())
352 nativeOut += ReserveToNativeRaw(it->second, exchangeRates[i]);
358 CAmount CCurrencyState::ReserveToNativeRaw(const CCurrencyValueMap &reserveAmounts,
359 const std::vector<uint160> ¤cies,
360 const std::vector<cpp_dec_float_50> &exchangeRates)
362 CAmount nativeOut = 0;
363 for (int i = 0; i < currencies.size(); i++)
365 auto it = reserveAmounts.valueMap.find(currencies[i]);
366 if (it != reserveAmounts.valueMap.end())
368 nativeOut += ReserveToNativeRaw(it->second, exchangeRates[i]);
374 CAmount CCurrencyState::ReserveToNativeRaw(const CCurrencyValueMap &reserveAmounts,
375 const std::vector<uint160> ¤cies,
376 const std::vector<CAmount> &exchangeRates)
378 CAmount nativeOut = 0;
379 for (int i = 0; i < currencies.size(); i++)
381 auto it = reserveAmounts.valueMap.find(currencies[i]);
382 if (it != reserveAmounts.valueMap.end())
384 nativeOut += ReserveToNativeRaw(it->second, exchangeRates[i]);
390 CAmount CCurrencyState::ReserveToNative(CAmount reserveAmount, int32_t reserveIndex) const
392 return ReserveToNativeRaw(reserveAmount, PriceInReserveDecFloat50(reserveIndex));
395 CAmount CCurrencyState::NativeToReserveRaw(CAmount nativeAmount, const cpp_dec_float_50 &price)
397 static cpp_dec_float_50 bigSatoshi(std::to_string((SATOSHIDEN)));
398 cpp_dec_float_50 bigAmount(std::to_string(nativeAmount));
400 cpp_dec_float_50 bigReserves = (bigAmount * price) / bigSatoshi;
401 if (to_int64(bigReserves, retVal))
408 CAmount CCurrencyState::NativeToReserveRaw(CAmount nativeAmount, CAmount exchangeRate)
410 return NativeToReserveRaw(nativeAmount, cpp_dec_float_50(std::to_string(exchangeRate)));
413 CAmount CCurrencyState::NativeToReserve(CAmount nativeAmount, int32_t reserveIndex) const
415 return NativeToReserveRaw(nativeAmount, PriceInReserveDecFloat50(reserveIndex));
418 CCurrencyValueMap CCurrencyState::NativeToReserveRaw(const std::vector<CAmount> &nativeAmount, const std::vector<CAmount> &exchangeRates) const
420 static arith_uint256 bigSatoshi(SATOSHIDEN);
421 CCurrencyValueMap retVal;
422 for (int i = 0; i < currencies.size(); i++)
424 retVal.valueMap[currencies[i]] = NativeToReserveRaw(nativeAmount[i], exchangeRates[i]);
429 CCurrencyValueMap CCurrencyState::NativeToReserveRaw(const std::vector<CAmount> &nativeAmount, const std::vector<cpp_dec_float_50> &exchangeRates) const
431 static arith_uint256 bigSatoshi(SATOSHIDEN);
432 CCurrencyValueMap retVal;
433 for (int i = 0; i < currencies.size(); i++)
435 retVal.valueMap[currencies[i]] = NativeToReserveRaw(nativeAmount[i], exchangeRates[i]);
440 CAmount CCurrencyState::ReserveToNative(const CCurrencyValueMap &reserveAmounts) const
442 CAmount nativeOut = 0;
443 for (int i = 0; i < currencies.size(); i++)
445 auto it = reserveAmounts.valueMap.find(currencies[i]);
446 if (it != reserveAmounts.valueMap.end())
448 nativeOut += ReserveToNative(it->second, i);
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,
460 UniValue retVal(UniValue::VOBJ);
463 for (int i = 0; i < rowNames.size(); i++)
465 UniValue row(UniValue::VOBJ);
466 for (int j = 0; j < columnNames.size(); j++)
468 row.push_back(Pair(columnNames[j], ValueFromAmount((*(vec[j])).size() > i ? (*(vec[j]))[i] : 0)));
470 retVal.push_back(Pair(rowNames[i], row));
475 for (int i = 0; i < rowNames.size(); i++)
477 UniValue row(UniValue::VOBJ);
478 for (int j = 0; j < columnNames.size(); j++)
480 row.push_back(Pair(columnNames[j], ValueFromAmount((*(vec[i])).size() > j ? (*(vec[i]))[j] : 0)));
482 retVal.push_back(Pair(rowNames[i], row));
488 UniValue CCoinbaseCurrencyState::ToUniValue() const
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++)
495 rowNames.push_back(EncodeDestination(CIdentityID(currencies[i])));
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};
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));
506 UniValue CPBaaSNotarization::ToUniValue() const
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)
525 nodesUni.push_back(node.ToUniValue());
527 obj.push_back(Pair("nodes", nodesUni));
531 UniValue CCurrencyDefinition::ToUniValue() const
533 UniValue obj(UniValue::VOBJ);
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));
544 obj.push_back(Pair("idregistrationprice", idRegistrationAmount));
545 obj.push_back(Pair("idreferrallevels", idReferralLevels));
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
551 UniValue notaryArr(UniValue::VARR);
552 for (auto ¬ary : notaries)
554 notaryArr.push_back(EncodeDestination(CIdentityID(notary)));
556 obj.push_back(Pair("notaries", notaryArr));
558 obj.push_back(Pair("minnotariesconfirm", minNotariesConfirm));
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));
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())
569 UniValue currencyArr(UniValue::VARR);
570 for (auto ¤cy : currencies)
572 currencyArr.push_back(EncodeDestination(CIdentityID(currency)));
574 obj.push_back(Pair("currencies", currencyArr));
579 UniValue weightArr(UniValue::VARR);
580 for (auto &weight : weights)
582 weightArr.push_back(ValueFromAmount(weight));
584 obj.push_back(Pair("weights", weightArr));
587 if (conversions.size())
589 UniValue conversionArr(UniValue::VARR);
590 for (auto &conversion : conversions)
592 conversionArr.push_back(ValueFromAmount(conversion));
594 obj.push_back(Pair("conversions", conversionArr));
597 if (minPreconvert.size())
599 UniValue minPreconvertArr(UniValue::VARR);
600 for (auto &oneMin : minPreconvert)
602 minPreconvertArr.push_back(ValueFromAmount(oneMin));
604 obj.push_back(Pair("minpreconversion", minPreconvertArr));
607 if (maxPreconvert.size())
609 UniValue maxPreconvertArr(UniValue::VARR);
610 for (auto &oneMax : maxPreconvert)
612 maxPreconvertArr.push_back(ValueFromAmount(oneMax));
614 obj.push_back(Pair("maxpreconversion", maxPreconvertArr));
617 if (preLaunchDiscount)
619 obj.push_back(Pair("prelaunchdiscount", ValueFromAmount(preLaunchDiscount)));
622 if (preAllocation.size())
624 UniValue preAllocationArr(UniValue::VARR);
625 for (auto &onePreAllocation : preAllocation)
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);
632 obj.push_back(Pair("preallocation", preAllocationArr));
635 if (contributions.size())
637 UniValue initialContributionArr(UniValue::VARR);
638 for (auto &oneCurContributions : contributions)
640 initialContributionArr.push_back(ValueFromAmount(oneCurContributions));
642 obj.push_back(Pair("initialcontributions", initialContributionArr));
645 if (preconverted.size())
647 UniValue preconversionArr(UniValue::VARR);
648 for (auto &onePreconversion : preconverted)
650 preconversionArr.push_back(ValueFromAmount(onePreconversion));
652 obj.push_back(Pair("preconversions", preconversionArr));
655 UniValue eraArr(UniValue::VARR);
656 for (int i = 0; i < rewards.size(); i++)
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);
665 obj.push_back(Pair("eras", eraArr));
669 UniValue CTokenOutput::ToUniValue() const
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)));
678 UniValue CReserveTransfer::ToUniValue() const
680 UniValue ret(((CTokenOutput *)this)->ToUniValue());
681 if (flags & PREALLOCATE)
683 ret.push_back(Pair("preallocation", true));
685 else if (flags & MINT_CURRENCY)
687 ret.push_back(Pair("mintedcurrency", true));
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)));
696 ret.push_back(Pair("fees", ValueFromAmount(nFees)));
697 ret.push_back(Pair("destinationcurrencyid", EncodeDestination(CIdentityID(destCurrencyID))));
699 switch (destination.type)
701 case CTransferDestination::DEST_PKH:
702 destStr = EncodeDestination(CKeyID(uint160(destination.destination)));
705 case CTransferDestination::DEST_SH:
706 destStr = EncodeDestination(CScriptID(uint160(destination.destination)));
709 case CTransferDestination::DEST_ID:
710 destStr = EncodeDestination(CIdentityID(uint160(destination.destination)));
713 case CTransferDestination::DEST_QUANTUM:
714 destStr = EncodeDestination(CQuantumID(uint160(destination.destination)));
718 destStr = HexStr(destination.destination);
721 ret.push_back(Pair("destination", destStr));
725 UniValue CReserveExchange::ToUniValue() const
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)));
733 ret.push_back(Pair("limitprice", ValueFromAmount(nLimit)));
735 ret.push_back(Pair("fillorkill", (bool)(flags & FILL_OR_KILL)));
736 if (flags & FILL_OR_KILL)
738 ret.push_back(Pair("validbeforeblock", (int32_t)nValidBefore));
740 ret.push_back(Pair("sendoutput", (bool)(flags & SEND_OUTPUT)));
744 UniValue CCrossChainExport::ToUniValue() const
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()));
755 UniValue CCrossChainImport::ToUniValue() const
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()));
765 UniValue CPrincipal::ToUniValue() const
767 UniValue obj(UniValue::VOBJ);
768 obj.push_back(Pair("version", (int32_t)nVersion));
769 obj.push_back(Pair("flags", (int32_t)flags));
771 UniValue primaryAddressesUni(UniValue::VARR);
772 for (int i = 0; i < primaryAddresses.size(); i++)
774 primaryAddressesUni.push_back(EncodeDestination(primaryAddresses[i]));
776 obj.push_back(Pair("primaryaddresses", primaryAddressesUni));
777 obj.push_back(Pair("minimumsignatures", minSigs));
781 UniValue CIdentity::ToUniValue() const
783 UniValue obj = ((CPrincipal *)this)->ToUniValue();
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));
789 UniValue hashes(UniValue::VOBJ);
790 for (auto &entry : contentMap)
792 hashes.push_back(Pair(entry.first.GetHex(), entry.second.GetHex()));
794 obj.push_back(Pair("contentmap", hashes));
796 obj.push_back(Pair("revocationauthority", EncodeDestination(CTxDestination(CIdentityID(revocationAuthority)))));
797 obj.push_back(Pair("recoveryauthority", EncodeDestination(CTxDestination(CIdentityID(recoveryAuthority)))));
798 if (privateAddresses.size())
800 obj.push_back(Pair("privateaddress", EncodePaymentAddress(privateAddresses[0])));
805 UniValue CMMRProof::ToUniValue() const
807 UniValue retObj(UniValue::VOBJ);
808 for (auto &proof : proofSequence)
810 UniValue branchArray(UniValue::VARR);
811 switch (proof->branchType)
813 case CMerkleBranchBase::BRANCH_BTC:
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)
820 branchArray.push_back(oneHash.GetHex());
822 retObj.push_back(Pair("hashes", branchArray));
825 case CMerkleBranchBase::BRANCH_MMRBLAKE_NODE:
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)
833 branchArray.push_back(oneHash.GetHex());
835 retObj.push_back(Pair("hashes", branchArray));
838 case CMerkleBranchBase::BRANCH_MMRBLAKE_POWERNODE:
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)
846 branchArray.push_back(oneHash.GetHex());
848 retObj.push_back(Pair("hashes", branchArray));
856 void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex, bool fIncludeAsm)
859 vector<CTxDestination> addresses;
861 // needs to be an object
864 out = UniValue(UniValue::VOBJ);
868 ExtractDestinations(scriptPubKey, type, addresses, nRequired);
869 out.push_back(Pair("type", GetTxnOutputType(type)));
872 if (scriptPubKey.IsPayToCryptoCondition(p) && p.version >= COptCCParams::VERSION_V2)
876 case EVAL_CURRENCY_DEFINITION:
878 CCurrencyDefinition definition;
880 if (p.vData.size() && (definition = CCurrencyDefinition(p.vData[0])).IsValid())
882 out.push_back(Pair("currencydefinition", definition.ToUniValue()));
886 out.push_back(Pair("currencydefinition", "invalid"));
891 case EVAL_SERVICEREWARD:
893 CServiceReward reward;
895 if (p.vData.size() && (reward = CServiceReward(p.vData[0])).IsValid())
897 out.push_back(Pair("pbaasServiceReward", reward.ToUniValue()));
901 out.push_back(Pair("pbaasServiceReward", "invalid"));
906 case EVAL_EARNEDNOTARIZATION:
907 case EVAL_ACCEPTEDNOTARIZATION:
909 CPBaaSNotarization notarization;
911 if (p.vData.size() && (notarization = CPBaaSNotarization(p.vData[0])).IsValid())
913 out.push_back(Pair("pbaasNotarization", notarization.ToUniValue()));
917 out.push_back(Pair("pbaasNotarization", "invalid"));
922 case EVAL_FINALIZE_NOTARIZATION:
924 CTransactionFinalization finalization;
928 finalization = CTransactionFinalization(p.vData[0]);
929 out.push_back(Pair("finalizeNotarization", finalization.ToUniValue()));
934 case EVAL_CURRENCYSTATE:
936 CCoinbaseCurrencyState cbcs;
938 if (p.vData.size() && (cbcs = CCoinbaseCurrencyState(p.vData[0])).IsValid())
940 out.push_back(Pair("currencystate", cbcs.ToUniValue()));
944 out.push_back(Pair("currencystate", "invalid"));
949 case EVAL_RESERVE_TRANSFER:
953 if (p.vData.size() && (rt = CReserveTransfer(p.vData[0])).IsValid())
955 out.push_back(Pair("reservetransfer", rt.ToUniValue()));
959 out.push_back(Pair("reservetransfer", "invalid"));
964 case EVAL_RESERVE_OUTPUT:
968 if (p.vData.size() && (ro = CTokenOutput(p.vData[0])).IsValid())
970 out.push_back(Pair("reserveoutput", ro.ToUniValue()));
974 out.push_back(Pair("reserveoutput", "invalid"));
979 case EVAL_RESERVE_EXCHANGE:
981 CReserveExchange rex;
983 if (p.vData.size() && (rex = CReserveExchange(p.vData[0])).IsValid())
985 out.push_back(Pair("reserveexchange", rex.ToUniValue()));
989 out.push_back(Pair("reserveexchange", "invalid"));
994 case EVAL_RESERVE_DEPOSIT:
998 if (p.vData.size() && (ro = CTokenOutput(p.vData[0])).IsValid())
1000 out.push_back(Pair("reservedeposit", ro.ToUniValue()));
1004 out.push_back(Pair("reservedeposit", "invalid"));
1009 case EVAL_CROSSCHAIN_EXPORT:
1011 CCrossChainExport ccx;
1013 if (p.vData.size() && (ccx = CCrossChainExport(p.vData[0])).IsValid())
1015 out.push_back(Pair("crosschainexport", ccx.ToUniValue()));
1019 out.push_back(Pair("crosschainexport", "invalid"));
1024 case EVAL_CROSSCHAIN_IMPORT:
1026 CCrossChainImport cci;
1028 if (p.vData.size() && (cci = CCrossChainImport(p.vData[0])).IsValid())
1030 out.push_back(Pair("crosschainimport", cci.ToUniValue()));
1034 out.push_back(Pair("crosschainimport", "invalid"));
1039 case EVAL_IDENTITY_PRIMARY:
1043 if (p.vData.size() && (identity = CIdentity(p.vData[0])).IsValid())
1045 out.push_back(Pair("identityprimary", identity.ToUniValue()));
1049 out.push_back(Pair("identityprimary", "invalid"));
1054 case EVAL_IDENTITY_REVOKE:
1055 out.push_back(Pair("identityrevoke", ""));
1058 case EVAL_IDENTITY_RECOVER:
1059 out.push_back(Pair("identityrecover", ""));
1062 case EVAL_IDENTITY_COMMITMENT:
1063 out.push_back(Pair("identitycommitment", ""));
1066 case EVAL_IDENTITY_RESERVATION:
1067 out.push_back(Pair("identityreservation", ""));
1070 case EVAL_STAKEGUARD:
1071 out.push_back(Pair("stakeguard", ""));
1074 case EVAL_FINALIZE_EXPORT:
1076 CTransactionFinalization finalization;
1080 finalization = CTransactionFinalization(p.vData[0]);
1081 out.push_back(Pair("finalizeexport", finalization.ToUniValue()));
1087 out.push_back(Pair("unknown", ""));
1091 if (addresses.size())
1093 out.push_back(Pair("reqSigs", nRequired));
1095 UniValue a(UniValue::VARR);
1096 for (const CTxDestination& addr : addresses) {
1097 a.push_back(EncodeDestination(addr));
1099 out.push_back(Pair("addresses", a));
1104 out.push_back(Pair("asm", ScriptToAsmStr(scriptPubKey)));
1109 out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
1113 void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry)
1115 entry.pushKV("txid", tx.GetHash().GetHex());
1116 entry.pushKV("version", tx.nVersion);
1117 entry.pushKV("locktime", (int64_t)tx.nLockTime);
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()));
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);
1132 in.pushKV("sequence", (int64_t)txin.nSequence);
1135 entry.pushKV("vin", vin);
1137 UniValue vout(UniValue::VARR);
1138 for (unsigned int i = 0; i < tx.vout.size(); i++) {
1139 const CTxOut& txout = tx.vout[i];
1141 UniValue out(UniValue::VOBJ);
1143 UniValue outValue(UniValue::VNUM, FormatMoney(txout.nValue));
1144 out.pushKV("value", outValue);
1145 out.pushKV("n", (int64_t)i);
1147 UniValue o(UniValue::VOBJ);
1148 ScriptPubKeyToUniv(txout.scriptPubKey, o, true, false);
1149 out.pushKV("scriptPubKey", o);
1150 vout.push_back(out);
1152 entry.pushKV("vout", vout);
1154 if (!hashBlock.IsNull())
1155 entry.pushKV("blockhash", hashBlock.GetHex());
1157 entry.pushKV("hex", EncodeHexTx(tx)); // the hex-encoded transaction. used the name "hex" to be consistent with the verbose output of "getrawtransaction".