| 426 | } |
| 427 | |
| 428 | void TxToUniv(const CTransaction& tx, const uint256& block_hash, UniValue& entry, bool include_hex, const CTxUndo* txundo, TxVerbosity verbosity, std::function<bool(const CTxOut&)> is_change_func) |
| 429 | { |
| 430 | CHECK_NONFATAL(verbosity >= TxVerbosity::SHOW_DETAILS); |
| 431 | |
| 432 | entry.pushKV("txid", tx.GetHash().GetHex()); |
| 433 | entry.pushKV("hash", tx.GetWitnessHash().GetHex()); |
| 434 | entry.pushKV("version", tx.version); |
| 435 | entry.pushKV("size", tx.ComputeTotalSize()); |
| 436 | entry.pushKV("vsize", (GetTransactionWeight(tx) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR); |
| 437 | entry.pushKV("weight", GetTransactionWeight(tx)); |
| 438 | entry.pushKV("locktime", tx.nLockTime); |
| 439 | |
| 440 | UniValue vin{UniValue::VARR}; |
| 441 | vin.reserve(tx.vin.size()); |
| 442 | |
| 443 | // If available, use Undo data to calculate the fee. Note that txundo == nullptr |
| 444 | // for coinbase transactions and for transactions where undo data is unavailable. |
| 445 | const bool have_undo = txundo != nullptr; |
| 446 | CAmount amt_total_in = 0; |
| 447 | CAmount amt_total_out = 0; |
| 448 | |
| 449 | for (unsigned int i = 0; i < tx.vin.size(); i++) { |
| 450 | const CTxIn& txin = tx.vin[i]; |
| 451 | UniValue in(UniValue::VOBJ); |
| 452 | if (tx.IsCoinBase()) { |
| 453 | in.pushKV("coinbase", HexStr(txin.scriptSig)); |
| 454 | } else { |
| 455 | in.pushKV("txid", txin.prevout.hash.GetHex()); |
| 456 | in.pushKV("vout", txin.prevout.n); |
| 457 | UniValue o(UniValue::VOBJ); |
| 458 | o.pushKV("asm", ScriptToAsmStr(txin.scriptSig, true)); |
| 459 | o.pushKV("hex", HexStr(txin.scriptSig)); |
| 460 | in.pushKV("scriptSig", std::move(o)); |
| 461 | } |
| 462 | if (!tx.vin[i].scriptWitness.IsNull()) { |
| 463 | UniValue txinwitness(UniValue::VARR); |
| 464 | txinwitness.reserve(tx.vin[i].scriptWitness.stack.size()); |
| 465 | for (const auto& item : tx.vin[i].scriptWitness.stack) { |
| 466 | txinwitness.push_back(HexStr(item)); |
| 467 | } |
| 468 | in.pushKV("txinwitness", std::move(txinwitness)); |
| 469 | } |
| 470 | if (have_undo) { |
| 471 | const Coin& prev_coin = txundo->vprevout[i]; |
| 472 | const CTxOut& prev_txout = prev_coin.out; |
| 473 | |
| 474 | amt_total_in += prev_txout.nValue; |
| 475 | |
| 476 | if (verbosity == TxVerbosity::SHOW_DETAILS_AND_PREVOUT) { |
| 477 | UniValue o_script_pub_key(UniValue::VOBJ); |
| 478 | ScriptToUniv(prev_txout.scriptPubKey, /*out=*/o_script_pub_key, /*include_hex=*/true, /*include_address=*/true); |
| 479 | |
| 480 | UniValue p(UniValue::VOBJ); |
| 481 | p.pushKV("generated", prev_coin.IsCoinBase()); |
| 482 | p.pushKV("height", prev_coin.nHeight); |
| 483 | p.pushKV("value", ValueFromAmount(prev_txout.nValue)); |
| 484 | p.pushKV("scriptPubKey", std::move(o_script_pub_key)); |
| 485 | in.pushKV("prevout", std::move(p)); |
no test coverage detected