]> Git Repo - VerusCoin.git/blame - src/core_write.cpp
testnet breaking changes - Implement index address, hardening, makefile fixes
[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"
2d8b9129 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));
2d8b9129 242 ret.push_back(Pair("currencyid", EncodeDestination(CIdentityID(currencyID))));
56a7b665 243
4005d836 244 if (IsValid() && IsFractional())
56a7b665 245 {
246 UniValue currencyArr(UniValue::VARR);
247 for (int i = 0; i < currencies.size(); i++)
248 {
249 UniValue currencyObj(UniValue::VOBJ);
250 currencyObj.push_back(Pair("currencyid", EncodeDestination(CIdentityID(currencies[i]))));
251 currencyObj.push_back(Pair("weight", ValueFromAmount(i < weights.size() ? weights[i] : 0)));
252 currencyObj.push_back(Pair("reserves", ValueFromAmount(i < reserves.size() ? reserves[i] : 0)));
253 currencyObj.push_back(Pair("priceinreserve", ValueFromAmount(PriceInReserve(i))));
254 currencyArr.push_back(currencyObj);
255 }
256 ret.push_back(Pair("reservecurrencies", currencyArr));
257 }
258 ret.push_back(Pair("initialsupply", ValueFromAmount(initialSupply)));
259 ret.push_back(Pair("emitted", ValueFromAmount(emitted)));
260 ret.push_back(Pair("supply", ValueFromAmount(supply)));
261 return ret;
262}
263
19ce962e 264CAmount CCurrencyState::PriceInReserve(int32_t reserveIndex, bool roundUp) const
d07e4ab8 265{
266 if (reserveIndex >= reserves.size())
267 {
268 return 0;
269 }
270 if (!IsFractional())
271 {
272 return reserves[reserveIndex];
273 }
d07e4ab8 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{
6b1e3a52 306 static cpp_dec_float_50 BigSatoshiSquared("10000000000000000");
307 static cpp_dec_float_50 BigZero("0");
308 if (reserveIndex >= reserves.size())
309 {
310 return BigZero;
311 }
312 if (!IsFractional())
313 {
314 return cpp_dec_float_50(std::to_string(reserves[reserveIndex]));
315 }
316 if (!supply || weights[reserveIndex] == 0)
317 {
318 return cpp_dec_float_50(std::to_string(weights[reserveIndex]));
319 }
d07e4ab8 320 cpp_dec_float_50 Supply(std::to_string((supply ? supply : 1)));
321 cpp_dec_float_50 Reserve(std::to_string(reserves[reserveIndex] ? reserves[reserveIndex] : SATOSHIDEN));
322 cpp_dec_float_50 Ratio(std::to_string(weights[reserveIndex]));
d07e4ab8 323 return (Reserve * BigSatoshiSquared) / (Supply * Ratio);
324}
325
326std::vector<CAmount> CCurrencyState::PricesInReserve() const
327{
328 std::vector<CAmount> retVal(currencies.size());
329 for (int i = 0; i < currencies.size(); i++)
330 {
331 retVal[i] = PriceInReserve(i);
332 }
333 return retVal;
334}
335
336CAmount CCurrencyState::ReserveToNativeRaw(CAmount reserveAmount, const cpp_dec_float_50 &price)
337{
338 static cpp_dec_float_50 bigSatoshi(std::to_string(SATOSHIDEN));
339 static cpp_dec_float_50 bigZero(std::to_string(0));
340 cpp_dec_float_50 bigAmount(std::to_string(reserveAmount));
341
342 bigAmount = price != bigZero ? (bigAmount * bigSatoshi) / price : bigZero;
343 int64_t retVal;
344 if (to_int64(bigAmount, retVal))
345 {
346 return retVal;
347 }
348 return 0;
349}
350
351CAmount CCurrencyState::ReserveToNativeRaw(CAmount reserveAmount, CAmount exchangeRate)
352{
353 return ReserveToNativeRaw(reserveAmount, cpp_dec_float_50(std::to_string(exchangeRate)));
354}
355
356CAmount CCurrencyState::ReserveToNativeRaw(const CCurrencyValueMap &reserveAmounts, const std::vector<CAmount> &exchangeRates) const
357{
358 CAmount nativeOut = 0;
359 for (int i = 0; i < currencies.size(); i++)
360 {
361 auto it = reserveAmounts.valueMap.find(currencies[i]);
362 if (it != reserveAmounts.valueMap.end())
363 {
364 nativeOut += ReserveToNativeRaw(it->second, exchangeRates[i]);
365 }
366 }
367 return nativeOut;
368}
369
370CAmount CCurrencyState::ReserveToNativeRaw(const CCurrencyValueMap &reserveAmounts,
371 const std::vector<uint160> &currencies,
372 const std::vector<cpp_dec_float_50> &exchangeRates)
373{
374 CAmount nativeOut = 0;
375 for (int i = 0; i < currencies.size(); i++)
376 {
377 auto it = reserveAmounts.valueMap.find(currencies[i]);
378 if (it != reserveAmounts.valueMap.end())
379 {
380 nativeOut += ReserveToNativeRaw(it->second, exchangeRates[i]);
381 }
382 }
383 return nativeOut;
384}
385
386CAmount CCurrencyState::ReserveToNativeRaw(const CCurrencyValueMap &reserveAmounts,
387 const std::vector<uint160> &currencies,
388 const std::vector<CAmount> &exchangeRates)
389{
390 CAmount nativeOut = 0;
391 for (int i = 0; i < currencies.size(); i++)
392 {
393 auto it = reserveAmounts.valueMap.find(currencies[i]);
394 if (it != reserveAmounts.valueMap.end())
395 {
396 nativeOut += ReserveToNativeRaw(it->second, exchangeRates[i]);
397 }
398 }
399 return nativeOut;
400}
401
402CAmount CCurrencyState::ReserveToNative(CAmount reserveAmount, int32_t reserveIndex) const
403{
404 return ReserveToNativeRaw(reserveAmount, PriceInReserveDecFloat50(reserveIndex));
405}
406
407CAmount CCurrencyState::NativeToReserveRaw(CAmount nativeAmount, const cpp_dec_float_50 &price)
408{
409 static cpp_dec_float_50 bigSatoshi(std::to_string((SATOSHIDEN)));
410 cpp_dec_float_50 bigAmount(std::to_string(nativeAmount));
411 int64_t retVal;
412 cpp_dec_float_50 bigReserves = (bigAmount * price) / bigSatoshi;
413 if (to_int64(bigReserves, retVal))
414 {
415 return retVal;
416 }
417 return 0;
418}
419
420CAmount CCurrencyState::NativeToReserveRaw(CAmount nativeAmount, CAmount exchangeRate)
421{
422 return NativeToReserveRaw(nativeAmount, cpp_dec_float_50(std::to_string(exchangeRate)));
423}
424
425CAmount CCurrencyState::NativeToReserve(CAmount nativeAmount, int32_t reserveIndex) const
426{
427 return NativeToReserveRaw(nativeAmount, PriceInReserveDecFloat50(reserveIndex));
428}
429
430CCurrencyValueMap CCurrencyState::NativeToReserveRaw(const std::vector<CAmount> &nativeAmount, const std::vector<CAmount> &exchangeRates) const
431{
432 static arith_uint256 bigSatoshi(SATOSHIDEN);
433 CCurrencyValueMap retVal;
434 for (int i = 0; i < currencies.size(); i++)
435 {
436 retVal.valueMap[currencies[i]] = NativeToReserveRaw(nativeAmount[i], exchangeRates[i]);
437 }
438 return retVal;
439}
440
441CCurrencyValueMap CCurrencyState::NativeToReserveRaw(const std::vector<CAmount> &nativeAmount, const std::vector<cpp_dec_float_50> &exchangeRates) const
442{
443 static arith_uint256 bigSatoshi(SATOSHIDEN);
444 CCurrencyValueMap retVal;
445 for (int i = 0; i < currencies.size(); i++)
446 {
447 retVal.valueMap[currencies[i]] = NativeToReserveRaw(nativeAmount[i], exchangeRates[i]);
448 }
449 return retVal;
450}
451
452CAmount CCurrencyState::ReserveToNative(const CCurrencyValueMap &reserveAmounts) const
453{
454 CAmount nativeOut = 0;
455 for (int i = 0; i < currencies.size(); i++)
456 {
457 auto it = reserveAmounts.valueMap.find(currencies[i]);
458 if (it != reserveAmounts.valueMap.end())
459 {
460 nativeOut += ReserveToNative(it->second, i);
461 }
462 }
463 return nativeOut;
464}
465
56a7b665 466template <typename INNERVECTOR>
467UniValue ValueVectorsToUniValue(const std::vector<std::string> &rowNames,
468 const std::vector<std::string> &columnNames,
469 const std::vector<INNERVECTOR *> &vec,
470 bool columnVectors)
471{
472 UniValue retVal(UniValue::VOBJ);
473 if (columnVectors)
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[j])).size() > i ? (*(vec[j]))[i] : 0)));
481 }
482 retVal.push_back(Pair(rowNames[i], row));
483 }
484 }
485 else
486 {
487 for (int i = 0; i < rowNames.size(); i++)
488 {
489 UniValue row(UniValue::VOBJ);
490 for (int j = 0; j < columnNames.size(); j++)
491 {
492 row.push_back(Pair(columnNames[j], ValueFromAmount((*(vec[i])).size() > j ? (*(vec[i]))[j] : 0)));
493 }
494 retVal.push_back(Pair(rowNames[i], row));
495 }
496 }
497 return retVal;
498}
499
500UniValue CCoinbaseCurrencyState::ToUniValue() const
501{
502 UniValue ret(UniValue::VOBJ);
c8c677c9 503 ret = ((CCurrencyState *)this)->ToUniValue();
56a7b665 504 std::vector<std::string> rowNames;
505 for (int i = 0; i < currencies.size(); i++)
506 {
507 rowNames.push_back(EncodeDestination(CIdentityID(currencies[i])));
508 }
509 std::vector<std::string> columnNames({"reservein", "nativein", "reserveout", "lastconversionprice", "fees", "conversionfees"});
510 std::vector<const std::vector<CAmount> *> data = {&reserveIn, &nativeIn, &reserveOut, &conversionPrice, &fees, &conversionFees};
511
512 ret.push_back(Pair("currencies", ValueVectorsToUniValue(rowNames, columnNames, data, true)));
513 ret.push_back(Pair("nativefees", nativeFees));
514 ret.push_back(Pair("nativeconversionfees", nativeConversionFees));
515 return ret;
516}
517
518UniValue CPBaaSNotarization::ToUniValue() const
519{
520 UniValue obj(UniValue::VOBJ);
521 obj.push_back(Pair("version", (int32_t)nVersion));
cc3d5cb5 522 obj.push_back(Pair("currencyid", EncodeDestination(CIdentityID(currencyID))));
56a7b665 523 obj.push_back(Pair("notaryaddress", EncodeDestination(notaryDest)));
524 obj.push_back(Pair("notarizationheight", (int32_t)notarizationHeight));
525 obj.push_back(Pair("mmrroot", mmrRoot.GetHex()));
526 obj.push_back(Pair("notarizationprehash", notarizationPreHash.GetHex()));
527 obj.push_back(Pair("work", ((UintToArith256(compactPower) << 128) >> 128).ToString()));
528 obj.push_back(Pair("stake", (UintToArith256(compactPower) >> 128).ToString()));
529 obj.push_back(Pair("currencystate", currencyState.ToUniValue()));
530 obj.push_back(Pair("prevnotarization", prevNotarization.GetHex()));
531 obj.push_back(Pair("prevheight", prevHeight));
532 obj.push_back(Pair("crossnotarization", crossNotarization.GetHex()));
533 obj.push_back(Pair("crossheight", crossHeight));
534 UniValue nodesUni(UniValue::VARR);
535 for (auto node : nodes)
536 {
537 nodesUni.push_back(node.ToUniValue());
538 }
539 obj.push_back(Pair("nodes", nodesUni));
540 return obj;
541}
542
543UniValue CCurrencyDefinition::ToUniValue() const
544{
545 UniValue obj(UniValue::VOBJ);
546
547 obj.push_back(Pair("name", name));
548 obj.push_back(Pair("version", (int64_t)nVersion));
549 obj.push_back(Pair("options", (int64_t)options));
550 obj.push_back(Pair("parent", EncodeDestination(CIdentityID(parent))));
551 obj.push_back(Pair("systemid", EncodeDestination(CIdentityID(systemID))));
552 obj.push_back(Pair("currencyid", EncodeDestination(CIdentityID(GetID()))));
553 obj.push_back(Pair("notarizationprotocol", (int)notarizationProtocol));
554 obj.push_back(Pair("proofprotocol", (int)proofProtocol));
555
556 obj.push_back(Pair("idregistrationprice", idRegistrationAmount));
557 obj.push_back(Pair("idreferrallevels", idReferralLevels));
558
559 // notaries are identities that perform specific functions for the currency's operation
560 // related to notarizing an external currency source, as well as proving imports
561 if (notaries.size())
562 {
563 UniValue notaryArr(UniValue::VARR);
564 for (auto &notary : notaries)
565 {
566 notaryArr.push_back(EncodeDestination(CIdentityID(notary)));
567 }
568 obj.push_back(Pair("notaries", notaryArr));
569 }
570 obj.push_back(Pair("minnotariesconfirm", minNotariesConfirm));
571
572 obj.push_back(Pair("billingperiod", billingPeriod));
573 obj.push_back(Pair("notarizationreward", notarizationReward));
574 obj.push_back(Pair("startblock", (int32_t)startBlock));
575 obj.push_back(Pair("endblock", (int32_t)endBlock));
576
577 // notaries are identities that perform specific functions for the currency's operation
578 // related to notarizing an external currency source, as well as proving imports
579 if (currencies.size())
580 {
581 UniValue currencyArr(UniValue::VARR);
582 for (auto &currency : currencies)
583 {
584 currencyArr.push_back(EncodeDestination(CIdentityID(currency)));
585 }
586 obj.push_back(Pair("currencies", currencyArr));
587 }
588
589 if (weights.size())
590 {
591 UniValue weightArr(UniValue::VARR);
592 for (auto &weight : weights)
593 {
594 weightArr.push_back(ValueFromAmount(weight));
595 }
596 obj.push_back(Pair("weights", weightArr));
597 }
598
599 if (conversions.size())
600 {
601 UniValue conversionArr(UniValue::VARR);
602 for (auto &conversion : conversions)
603 {
604 conversionArr.push_back(ValueFromAmount(conversion));
605 }
606 obj.push_back(Pair("conversions", conversionArr));
607 }
608
609 if (minPreconvert.size())
610 {
611 UniValue minPreconvertArr(UniValue::VARR);
612 for (auto &oneMin : minPreconvert)
613 {
614 minPreconvertArr.push_back(ValueFromAmount(oneMin));
615 }
616 obj.push_back(Pair("minpreconversion", minPreconvertArr));
617 }
618
619 if (maxPreconvert.size())
620 {
621 UniValue maxPreconvertArr(UniValue::VARR);
622 for (auto &oneMax : maxPreconvert)
623 {
624 maxPreconvertArr.push_back(ValueFromAmount(oneMax));
625 }
626 obj.push_back(Pair("maxpreconversion", maxPreconvertArr));
627 }
628
1fb6db72 629 if (preLaunchDiscount)
56a7b665 630 {
68ddda5e 631 obj.push_back(Pair("prelaunchdiscount", ValueFromAmount(preLaunchDiscount)));
56a7b665 632 }
633
634 if (preAllocation.size())
635 {
636 UniValue preAllocationArr(UniValue::VARR);
637 for (auto &onePreAllocation : preAllocation)
638 {
639 UniValue onePreAlloc(UniValue::VOBJ);
640 onePreAlloc.push_back(Pair(onePreAllocation.first.IsNull() ? "blockoneminer" : EncodeDestination(CIdentityID(onePreAllocation.first)),
641 ValueFromAmount(onePreAllocation.second)));
642 preAllocationArr.push_back(onePreAlloc);
643 }
644 obj.push_back(Pair("preallocation", preAllocationArr));
645 }
646
647 if (contributions.size())
648 {
649 UniValue initialContributionArr(UniValue::VARR);
650 for (auto &oneCurContributions : contributions)
651 {
652 initialContributionArr.push_back(ValueFromAmount(oneCurContributions));
653 }
654 obj.push_back(Pair("initialcontributions", initialContributionArr));
655 }
656
657 if (preconverted.size())
658 {
659 UniValue preconversionArr(UniValue::VARR);
660 for (auto &onePreconversion : preconverted)
661 {
662 preconversionArr.push_back(ValueFromAmount(onePreconversion));
663 }
664 obj.push_back(Pair("preconversions", preconversionArr));
665 }
666
667 UniValue eraArr(UniValue::VARR);
668 for (int i = 0; i < rewards.size(); i++)
669 {
670 UniValue era(UniValue::VOBJ);
671 era.push_back(Pair("reward", rewards.size() > i ? rewards[i] : (int64_t)0));
672 era.push_back(Pair("decay", rewardsDecay.size() > i ? rewardsDecay[i] : (int64_t)0));
673 era.push_back(Pair("halving", halving.size() > i ? (int32_t)halving[i] : (int32_t)0));
674 era.push_back(Pair("eraend", eraEnd.size() > i ? (int32_t)eraEnd[i] : (int32_t)0));
675 eraArr.push_back(era);
676 }
677 obj.push_back(Pair("eras", eraArr));
678 return obj;
679}
680
681UniValue CTokenOutput::ToUniValue() const
682{
683 UniValue ret(UniValue::VOBJ);
684 ret.push_back(Pair("version", (int64_t)nVersion));
5781675d 685 ret.push_back(Pair("currencyid", currencyID.IsNull() ? "NULL" : EncodeDestination(CIdentityID(currencyID))));
56a7b665 686 ret.push_back(Pair("value", ValueFromAmount(nValue)));
687 return ret;
688}
689
2d8b9129 690UniValue CReserveDeposit::ToUniValue() const
691{
692 UniValue ret(UniValue::VOBJ);
693 ret.push_back(Pair("version", (int64_t)nVersion));
694 ret.push_back(Pair("controllingcurrencyid", controllingCurrencyID.IsNull() ? "NULL" : EncodeDestination(CIdentityID(controllingCurrencyID))));
695 ret.push_back(Pair("reserveValues", reserveValues.ToUniValue()));
696 return ret;
697}
698
56a7b665 699UniValue CReserveTransfer::ToUniValue() const
700{
701 UniValue ret(((CTokenOutput *)this)->ToUniValue());
15197dca 702 if (flags & PREALLOCATE)
703 {
704 ret.push_back(Pair("preallocation", true));
705 }
706 else if (flags & MINT_CURRENCY)
707 {
708 ret.push_back(Pair("mintedcurrency", true));
709 }
710 else
711 {
712 ret.push_back(Pair("convert", (bool)(flags & CONVERT)));
713 ret.push_back(Pair("preconvert", (bool)(flags & PRECONVERT)));
714 ret.push_back(Pair("feeoutput", (bool)(flags & FEE_OUTPUT)));
715 ret.push_back(Pair("sendback", (bool)(flags & SEND_BACK)));
716 }
56a7b665 717 ret.push_back(Pair("fees", ValueFromAmount(nFees)));
718 ret.push_back(Pair("destinationcurrencyid", EncodeDestination(CIdentityID(destCurrencyID))));
719 std::string destStr;
720 switch (destination.type)
721 {
722 case CTransferDestination::DEST_PKH:
723 destStr = EncodeDestination(CKeyID(uint160(destination.destination)));
724 break;
725
726 case CTransferDestination::DEST_SH:
727 destStr = EncodeDestination(CScriptID(uint160(destination.destination)));
728 break;
729
730 case CTransferDestination::DEST_ID:
731 destStr = EncodeDestination(CIdentityID(uint160(destination.destination)));
732 break;
733
734 case CTransferDestination::DEST_QUANTUM:
735 destStr = EncodeDestination(CQuantumID(uint160(destination.destination)));
736 break;
737
738 default:
739 destStr = HexStr(destination.destination);
740 break;
741 }
742 ret.push_back(Pair("destination", destStr));
743 return ret;
744}
745
746UniValue CReserveExchange::ToUniValue() const
747{
748 UniValue ret(((CTokenOutput *)this)->ToUniValue());
749 ret.push_back(Pair("toreserve", (bool)(flags & TO_RESERVE)));
750 ret.push_back(Pair("tonative", !((bool)(flags & TO_RESERVE))));
751 ret.push_back(Pair("limitorder", (bool)(flags & LIMIT)));
752 if (flags & LIMIT)
753 {
754 ret.push_back(Pair("limitprice", ValueFromAmount(nLimit)));
755 }
756 ret.push_back(Pair("fillorkill", (bool)(flags & FILL_OR_KILL)));
757 if (flags & FILL_OR_KILL)
758 {
759 ret.push_back(Pair("validbeforeblock", (int32_t)nValidBefore));
760 }
761 ret.push_back(Pair("sendoutput", (bool)(flags & SEND_OUTPUT)));
762 return ret;
763}
764
765UniValue CCrossChainExport::ToUniValue() const
766{
767 UniValue obj(UniValue::VOBJ);
768 obj.push_back(Pair("version", (int)nVersion));
2d8b9129 769 obj.push_back(Pair("exportcurrencyid", EncodeDestination(CIdentityID(systemID))));
56a7b665 770 obj.push_back(Pair("numinputs", numInputs));
771 obj.push_back(Pair("totalamounts", totalAmounts.ToUniValue()));
772 obj.push_back(Pair("totalfees", totalFees.ToUniValue()));
773 return obj;
774}
775
776UniValue CCrossChainImport::ToUniValue() const
777{
778 UniValue obj(UniValue::VOBJ);
779 obj.push_back(Pair("version", (int)nVersion));
2d8b9129 780 obj.push_back(Pair("sourcesystemid", EncodeDestination(CIdentityID(systemID))));
781 obj.push_back(Pair("importcurrencyid", EncodeDestination(CIdentityID(importCurrencyID))));
56a7b665 782 obj.push_back(Pair("valuein", importValue.ToUniValue()));
7beb1c0b 783 obj.push_back(Pair("tokensout", totalReserveOutMap.ToUniValue()));
56a7b665 784 return obj;
785}
786
2d8b9129 787UniValue CTransactionFinalization::ToUniValue() const
788{
789 UniValue ret(UniValue::VOBJ);
790 ret.push_back(Pair("finalizationtype", (finalizationType == FINALIZE_NOTARIZATION) ?
791 "finalizenotarization" : finalizationType == FINALIZE_EXPORT ?
792 "finalizeexport" : "invalid"));
793 ret.push_back(Pair("currencyid", EncodeDestination(CIdentityID(currencyID))));
794 ret.push_back(Pair("confirmedinput", confirmedInput));
795 return ret;
796}
797
56a7b665 798UniValue CPrincipal::ToUniValue() const
799{
800 UniValue obj(UniValue::VOBJ);
801 obj.push_back(Pair("version", (int32_t)nVersion));
802 obj.push_back(Pair("flags", (int32_t)flags));
803
804 UniValue primaryAddressesUni(UniValue::VARR);
805 for (int i = 0; i < primaryAddresses.size(); i++)
806 {
807 primaryAddressesUni.push_back(EncodeDestination(primaryAddresses[i]));
808 }
809 obj.push_back(Pair("primaryaddresses", primaryAddressesUni));
810 obj.push_back(Pair("minimumsignatures", minSigs));
811 return obj;
812}
813
814UniValue CIdentity::ToUniValue() const
815{
816 UniValue obj = ((CPrincipal *)this)->ToUniValue();
817
818 obj.push_back(Pair("identityaddress", EncodeDestination(CIdentityID(GetID()))));
819 obj.push_back(Pair("parent", EncodeDestination(CIdentityID(parent))));
820 obj.push_back(Pair("name", name));
821
822 UniValue hashes(UniValue::VOBJ);
823 for (auto &entry : contentMap)
824 {
825 hashes.push_back(Pair(entry.first.GetHex(), entry.second.GetHex()));
826 }
827 obj.push_back(Pair("contentmap", hashes));
828
829 obj.push_back(Pair("revocationauthority", EncodeDestination(CTxDestination(CIdentityID(revocationAuthority)))));
830 obj.push_back(Pair("recoveryauthority", EncodeDestination(CTxDestination(CIdentityID(recoveryAuthority)))));
831 if (privateAddresses.size())
832 {
833 obj.push_back(Pair("privateaddress", EncodePaymentAddress(privateAddresses[0])));
834 }
835 return obj;
836}
837
e8b83707 838UniValue CMMRProof::ToUniValue() const
839{
840 UniValue retObj(UniValue::VOBJ);
841 for (auto &proof : proofSequence)
842 {
843 UniValue branchArray(UniValue::VARR);
844 switch (proof->branchType)
845 {
846 case CMerkleBranchBase::BRANCH_BTC:
847 {
848 CBTCMerkleBranch &branch = *(CBTCMerkleBranch *)(proof);
849 retObj.push_back(Pair("branchtype", "BTC"));
850 retObj.push_back(Pair("index", (int64_t)(branch.nIndex)));
851 for (auto &oneHash : branch.branch)
852 {
853 branchArray.push_back(oneHash.GetHex());
854 }
855 retObj.push_back(Pair("hashes", branchArray));
856 break;
857 }
858 case CMerkleBranchBase::BRANCH_MMRBLAKE_NODE:
859 {
860 CMMRNodeBranch &branch = *(CMMRNodeBranch *)(proof);
861 retObj.push_back(Pair("branchtype", "MMRBLAKENODE"));
862 retObj.push_back(Pair("index", (int64_t)(branch.nIndex)));
863 retObj.push_back(Pair("mmvsize", (int64_t)(branch.nSize)));
864 for (auto &oneHash : branch.branch)
865 {
866 branchArray.push_back(oneHash.GetHex());
867 }
868 retObj.push_back(Pair("hashes", branchArray));
869 break;
870 }
871 case CMerkleBranchBase::BRANCH_MMRBLAKE_POWERNODE:
872 {
873 CMMRPowerNodeBranch &branch = *(CMMRPowerNodeBranch *)(proof);
874 retObj.push_back(Pair("branchtype", "MMRBLAKEPOWERNODE"));
875 retObj.push_back(Pair("index", (int64_t)(branch.nIndex)));
876 retObj.push_back(Pair("mmvsize", (int64_t)(branch.nSize)));
877 for (auto &oneHash : branch.branch)
878 {
879 branchArray.push_back(oneHash.GetHex());
880 }
881 retObj.push_back(Pair("hashes", branchArray));
882 break;
883 }
884 };
885 }
886 return retObj;
887}
888
56a7b665 889void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex, bool fIncludeAsm)
890{
891 txnouttype type;
892 vector<CTxDestination> addresses;
893
894 // needs to be an object
895 if (!out.isObject())
896 {
897 out = UniValue(UniValue::VOBJ);
898 }
899
900 int nRequired;
901 ExtractDestinations(scriptPubKey, type, addresses, nRequired);
902 out.push_back(Pair("type", GetTxnOutputType(type)));
903
904 COptCCParams p;
905 if (scriptPubKey.IsPayToCryptoCondition(p) && p.version >= COptCCParams::VERSION_V2)
906 {
907 switch(p.evalCode)
908 {
909 case EVAL_CURRENCY_DEFINITION:
910 {
911 CCurrencyDefinition definition;
912
913 if (p.vData.size() && (definition = CCurrencyDefinition(p.vData[0])).IsValid())
914 {
7beb1c0b 915 out.push_back(Pair("currencydefinition", definition.ToUniValue()));
56a7b665 916 }
917 else
918 {
7beb1c0b 919 out.push_back(Pair("currencydefinition", "invalid"));
56a7b665 920 }
921 break;
922 }
923
924 case EVAL_SERVICEREWARD:
925 {
926 CServiceReward reward;
927
928 if (p.vData.size() && (reward = CServiceReward(p.vData[0])).IsValid())
929 {
930 out.push_back(Pair("pbaasServiceReward", reward.ToUniValue()));
931 }
932 else
933 {
934 out.push_back(Pair("pbaasServiceReward", "invalid"));
935 }
936 break;
937 }
938
939 case EVAL_EARNEDNOTARIZATION:
940 case EVAL_ACCEPTEDNOTARIZATION:
941 {
942 CPBaaSNotarization notarization;
943
944 if (p.vData.size() && (notarization = CPBaaSNotarization(p.vData[0])).IsValid())
945 {
946 out.push_back(Pair("pbaasNotarization", notarization.ToUniValue()));
947 }
948 else
949 {
950 out.push_back(Pair("pbaasNotarization", "invalid"));
951 }
952 break;
953 }
954
09b977c6 955 case EVAL_FINALIZE_NOTARIZATION:
56a7b665 956 {
09b977c6 957 CTransactionFinalization finalization;
56a7b665 958
959 if (p.vData.size())
960 {
09b977c6 961 finalization = CTransactionFinalization(p.vData[0]);
962 out.push_back(Pair("finalizeNotarization", finalization.ToUniValue()));
56a7b665 963 }
964 break;
965 }
966
967 case EVAL_CURRENCYSTATE:
968 {
969 CCoinbaseCurrencyState cbcs;
970
971 if (p.vData.size() && (cbcs = CCoinbaseCurrencyState(p.vData[0])).IsValid())
972 {
973 out.push_back(Pair("currencystate", cbcs.ToUniValue()));
974 }
975 else
976 {
977 out.push_back(Pair("currencystate", "invalid"));
978 }
979 break;
980 }
981
982 case EVAL_RESERVE_TRANSFER:
983 {
984 CReserveTransfer rt;
985
986 if (p.vData.size() && (rt = CReserveTransfer(p.vData[0])).IsValid())
987 {
988 out.push_back(Pair("reservetransfer", rt.ToUniValue()));
989 }
990 else
991 {
992 out.push_back(Pair("reservetransfer", "invalid"));
993 }
994 break;
995 }
996
997 case EVAL_RESERVE_OUTPUT:
998 {
999 CTokenOutput ro;
1000
1001 if (p.vData.size() && (ro = CTokenOutput(p.vData[0])).IsValid())
1002 {
1003 out.push_back(Pair("reserveoutput", ro.ToUniValue()));
1004 }
1005 else
1006 {
1007 out.push_back(Pair("reserveoutput", "invalid"));
1008 }
1009 break;
1010 }
1011
1012 case EVAL_RESERVE_EXCHANGE:
1013 {
1014 CReserveExchange rex;
1015
1016 if (p.vData.size() && (rex = CReserveExchange(p.vData[0])).IsValid())
1017 {
1018 out.push_back(Pair("reserveexchange", rex.ToUniValue()));
1019 }
1020 else
1021 {
1022 out.push_back(Pair("reserveexchange", "invalid"));
1023 }
1024 break;
1025 }
1026
1027 case EVAL_RESERVE_DEPOSIT:
1028 {
2d8b9129 1029 CReserveDeposit rd;
56a7b665 1030
2d8b9129 1031 if (p.vData.size() && (rd = CReserveDeposit(p.vData[0])).IsValid())
56a7b665 1032 {
2d8b9129 1033 out.push_back(Pair("reservedeposit", rd.ToUniValue()));
56a7b665 1034 }
1035 else
1036 {
1037 out.push_back(Pair("reservedeposit", "invalid"));
1038 }
1039 break;
1040 }
1041
1042 case EVAL_CROSSCHAIN_EXPORT:
1043 {
1044 CCrossChainExport ccx;
1045
1046 if (p.vData.size() && (ccx = CCrossChainExport(p.vData[0])).IsValid())
1047 {
1048 out.push_back(Pair("crosschainexport", ccx.ToUniValue()));
1049 }
1050 else
1051 {
1052 out.push_back(Pair("crosschainexport", "invalid"));
1053 }
1054 break;
1055 }
1056
1057 case EVAL_CROSSCHAIN_IMPORT:
1058 {
1059 CCrossChainImport cci;
1060
1061 if (p.vData.size() && (cci = CCrossChainImport(p.vData[0])).IsValid())
1062 {
1063 out.push_back(Pair("crosschainimport", cci.ToUniValue()));
1064 }
1065 else
1066 {
1067 out.push_back(Pair("crosschainimport", "invalid"));
1068 }
1069 break;
1070 }
1071
1072 case EVAL_IDENTITY_PRIMARY:
1073 {
1074 CIdentity identity;
1075
1076 if (p.vData.size() && (identity = CIdentity(p.vData[0])).IsValid())
1077 {
1078 out.push_back(Pair("identityprimary", identity.ToUniValue()));
1079 }
1080 else
1081 {
1082 out.push_back(Pair("identityprimary", "invalid"));
1083 }
1084 break;
1085 }
1086
1087 case EVAL_IDENTITY_REVOKE:
1088 out.push_back(Pair("identityrevoke", ""));
1089 break;
1090
1091 case EVAL_IDENTITY_RECOVER:
1092 out.push_back(Pair("identityrecover", ""));
1093 break;
1094
1095 case EVAL_IDENTITY_COMMITMENT:
1096 out.push_back(Pair("identitycommitment", ""));
1097 break;
1098
1099 case EVAL_IDENTITY_RESERVATION:
1100 out.push_back(Pair("identityreservation", ""));
1101 break;
1102
1103 case EVAL_STAKEGUARD:
1104 out.push_back(Pair("stakeguard", ""));
1105 break;
1106
09b977c6 1107 case EVAL_FINALIZE_EXPORT:
56a7b665 1108 {
09b977c6 1109 CTransactionFinalization finalization;
56a7b665 1110
09b977c6 1111 if (p.vData.size())
56a7b665 1112 {
09b977c6 1113 finalization = CTransactionFinalization(p.vData[0]);
05cef42a 1114 out.push_back(Pair("finalizeexport", finalization.ToUniValue()));
56a7b665 1115 }
1116 break;
1117 }
1118
1119 default:
1120 out.push_back(Pair("unknown", ""));
1121 }
1122 }
1123
1124 if (addresses.size())
1125 {
1126 out.push_back(Pair("reqSigs", nRequired));
1127
1128 UniValue a(UniValue::VARR);
1129 for (const CTxDestination& addr : addresses) {
1130 a.push_back(EncodeDestination(addr));
1131 }
1132 out.push_back(Pair("addresses", a));
1133 }
1134
1135 if (fIncludeAsm)
1136 {
1137 out.push_back(Pair("asm", ScriptToAsmStr(scriptPubKey)));
1138 }
1139
1140 if (fIncludeHex)
1141 {
1142 out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
1143 }
1144}
1145
cbe39a38
JG
1146void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry)
1147{
805344dc 1148 entry.pushKV("txid", tx.GetHash().GetHex());
cbe39a38
JG
1149 entry.pushKV("version", tx.nVersion);
1150 entry.pushKV("locktime", (int64_t)tx.nLockTime);
1151
1152 UniValue vin(UniValue::VARR);
1153 BOOST_FOREACH(const CTxIn& txin, tx.vin) {
1154 UniValue in(UniValue::VOBJ);
1155 if (tx.IsCoinBase())
1156 in.pushKV("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
1157 else {
1158 in.pushKV("txid", txin.prevout.hash.GetHex());
1159 in.pushKV("vout", (int64_t)txin.prevout.n);
1160 UniValue o(UniValue::VOBJ);
690d38f0 1161 o.pushKV("asm", ScriptToAsmStr(txin.scriptSig, true));
cbe39a38
JG
1162 o.pushKV("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
1163 in.pushKV("scriptSig", o);
1164 }
1165 in.pushKV("sequence", (int64_t)txin.nSequence);
1166 vin.push_back(in);
1167 }
1168 entry.pushKV("vin", vin);
1169
1170 UniValue vout(UniValue::VARR);
1171 for (unsigned int i = 0; i < tx.vout.size(); i++) {
1172 const CTxOut& txout = tx.vout[i];
1173
1174 UniValue out(UniValue::VOBJ);
1175
1176 UniValue outValue(UniValue::VNUM, FormatMoney(txout.nValue));
1177 out.pushKV("value", outValue);
1178 out.pushKV("n", (int64_t)i);
1179
1180 UniValue o(UniValue::VOBJ);
56a7b665 1181 ScriptPubKeyToUniv(txout.scriptPubKey, o, true, false);
cbe39a38
JG
1182 out.pushKV("scriptPubKey", o);
1183 vout.push_back(out);
1184 }
1185 entry.pushKV("vout", vout);
1186
4f152496 1187 if (!hashBlock.IsNull())
cbe39a38 1188 entry.pushKV("blockhash", hashBlock.GetHex());
84877904 1189
1190 entry.pushKV("hex", EncodeHexTx(tx)); // the hex-encoded transaction. used the name "hex" to be consistent with the verbose output of "getrawtransaction".
cbe39a38 1191}
This page took 0.336554 seconds and 4 git commands to generate.