| 1445 | } |
| 1446 | |
| 1447 | static RPCHelpMan gettxout() |
| 1448 | { |
| 1449 | return RPCHelpMan{"gettxout", |
| 1450 | "\nReturns details about an unspent transaction output.\n", |
| 1451 | { |
| 1452 | {"txid", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction id"}, |
| 1453 | {"n", RPCArg::Type::NUM, RPCArg::Optional::NO, "vout number"}, |
| 1454 | {"include_mempool", RPCArg::Type::BOOL, RPCArg::Default{true}, "Whether to include the mempool. Note that an unspent output that is spent in the mempool won't appear."}, |
| 1455 | }, |
| 1456 | { |
| 1457 | RPCResult{"If the UTXO was not found", RPCResult::Type::NONE, "", ""}, |
| 1458 | RPCResult{"Otherwise", RPCResult::Type::OBJ, "", "", { |
| 1459 | {RPCResult::Type::STR_HEX, "bestblock", "The hash of the block at the tip of the chain"}, |
| 1460 | {RPCResult::Type::NUM, "confirmations", "The number of confirmations"}, |
| 1461 | {RPCResult::Type::STR_AMOUNT, "value", "The transaction value in " + CURRENCY_UNIT}, |
| 1462 | {RPCResult::Type::OBJ, "scriptPubKey", "", { |
| 1463 | {RPCResult::Type::STR, "asm", ""}, |
| 1464 | {RPCResult::Type::STR, "desc", "Inferred descriptor for the output"}, |
| 1465 | {RPCResult::Type::STR_HEX, "hex", ""}, |
| 1466 | {RPCResult::Type::STR, "type", "The type, eg pubkeyhash"}, |
| 1467 | {RPCResult::Type::STR, "address", /*optional=*/true, "The Bitcoin address (only if a well-defined address exists)"}, |
| 1468 | }}, |
| 1469 | {RPCResult::Type::BOOL, "coinbase", "Coinbase or not"}, |
| 1470 | }}, |
| 1471 | }, |
| 1472 | RPCExamples{ |
| 1473 | "\nGet unspent transactions\n" |
| 1474 | + HelpExampleCli("listunspent", "") + |
| 1475 | "\nView the details\n" |
| 1476 | + HelpExampleCli("gettxout", "\"txid\" 1") + |
| 1477 | "\nAs a JSON-RPC call\n" |
| 1478 | + HelpExampleRpc("gettxout", "\"txid\", 1") |
| 1479 | }, |
| 1480 | [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue |
| 1481 | { |
| 1482 | NodeContext& node = EnsureAnyNodeContext(request.context); |
| 1483 | ChainstateManager& chainman = EnsureChainman(node); |
| 1484 | LOCK(cs_main); |
| 1485 | |
| 1486 | UniValue ret(UniValue::VOBJ); |
| 1487 | |
| 1488 | uint256 hash(ParseHashV(request.params[0], "txid")); |
| 1489 | int n = request.params[1].get_int(); |
| 1490 | COutPoint out(hash, n); |
| 1491 | bool fMempool = true; |
| 1492 | if (!request.params[2].isNull()) |
| 1493 | fMempool = request.params[2].get_bool(); |
| 1494 | |
| 1495 | Coin coin; |
| 1496 | CChainState& active_chainstate = chainman.ActiveChainstate(); |
| 1497 | CCoinsViewCache* coins_view = &active_chainstate.CoinsTip(); |
| 1498 | |
| 1499 | if (fMempool) { |
| 1500 | const CTxMemPool& mempool = EnsureMemPool(node); |
| 1501 | LOCK(mempool.cs); |
| 1502 | CCoinsViewMemPool view(coins_view, mempool); |
| 1503 | if (!view.GetCoin(out, coin) || mempool.isSpent(out)) { |
| 1504 | return NullUniValue; |
nothing calls this directly
no test coverage detected