| 1190 | } |
| 1191 | |
| 1192 | static RPCMethod gettxout() |
| 1193 | { |
| 1194 | return RPCMethod{ |
| 1195 | "gettxout", |
| 1196 | "Returns details about an unspent transaction output.\n", |
| 1197 | { |
| 1198 | {"txid", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction id"}, |
| 1199 | {"n", RPCArg::Type::NUM, RPCArg::Optional::NO, "vout number"}, |
| 1200 | {"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."}, |
| 1201 | }, |
| 1202 | { |
| 1203 | RPCResult{"If the UTXO was not found", RPCResult::Type::NONE, "", ""}, |
| 1204 | RPCResult{"Otherwise", RPCResult::Type::OBJ, "", "", { |
| 1205 | {RPCResult::Type::STR_HEX, "bestblock", "The hash of the block at the tip of the chain"}, |
| 1206 | {RPCResult::Type::NUM, "confirmations", "The number of confirmations"}, |
| 1207 | {RPCResult::Type::STR_AMOUNT, "value", "The transaction value in " + CURRENCY_UNIT}, |
| 1208 | {RPCResult::Type::OBJ, "scriptPubKey", "", { |
| 1209 | {RPCResult::Type::STR, "asm", "Disassembly of the output script"}, |
| 1210 | {RPCResult::Type::STR, "desc", "Inferred descriptor for the output"}, |
| 1211 | {RPCResult::Type::STR_HEX, "hex", "The raw output script bytes, hex-encoded"}, |
| 1212 | {RPCResult::Type::STR, "type", "The type, eg pubkeyhash"}, |
| 1213 | {RPCResult::Type::STR, "address", /*optional=*/true, "The Bitcoin address (only if a well-defined address exists)"}, |
| 1214 | }}, |
| 1215 | {RPCResult::Type::BOOL, "coinbase", "Coinbase or not"}, |
| 1216 | }}, |
| 1217 | }, |
| 1218 | RPCExamples{ |
| 1219 | "\nGet unspent transactions\n" |
| 1220 | + HelpExampleCli("listunspent", "") + |
| 1221 | "\nView the details\n" |
| 1222 | + HelpExampleCli("gettxout", "\"txid\" 1") + |
| 1223 | "\nAs a JSON-RPC call\n" |
| 1224 | + HelpExampleRpc("gettxout", "\"txid\", 1") |
| 1225 | }, |
| 1226 | [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue |
| 1227 | { |
| 1228 | NodeContext& node = EnsureAnyNodeContext(request.context); |
| 1229 | ChainstateManager& chainman = EnsureChainman(node); |
| 1230 | LOCK(cs_main); |
| 1231 | |
| 1232 | UniValue ret(UniValue::VOBJ); |
| 1233 | |
| 1234 | auto hash{Txid::FromUint256(ParseHashV(request.params[0], "txid"))}; |
| 1235 | COutPoint out{hash, request.params[1].getInt<uint32_t>()}; |
| 1236 | bool fMempool = true; |
| 1237 | if (!request.params[2].isNull()) |
| 1238 | fMempool = request.params[2].get_bool(); |
| 1239 | |
| 1240 | Chainstate& active_chainstate = chainman.ActiveChainstate(); |
| 1241 | CCoinsViewCache* coins_view = &active_chainstate.CoinsTip(); |
| 1242 | |
| 1243 | std::optional<Coin> coin; |
| 1244 | if (fMempool) { |
| 1245 | const CTxMemPool& mempool = EnsureMemPool(node); |
| 1246 | LOCK(mempool.cs); |
| 1247 | CCoinsViewMemPool view(coins_view, mempool); |
| 1248 | if (!mempool.isSpent(out)) coin = view.GetCoin(out); |
| 1249 | } else { |
nothing calls this directly
no test coverage detected