MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / gettxoutproof

Function gettxoutproof

src/rpc/txoutproof.cpp:23–127  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

21using node::GetTransaction;
22
23static RPCMethod gettxoutproof()
24{
25 return RPCMethod{
26 "gettxoutproof",
27 "Returns a hex-encoded proof that \"txid\" was included in a block.\n"
28 "\nNOTE: By default this function only works sometimes. This is when there is an\n"
29 "unspent output in the utxo for this transaction. To make it always work,\n"
30 "you need to maintain a transaction index, using the -txindex command line option or\n"
31 "specify the block in which the transaction is included manually (by blockhash).\n",
32 {
33 {"txids", RPCArg::Type::ARR, RPCArg::Optional::NO, "The txids to filter",
34 {
35 {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "A transaction hash"},
36 },
37 },
38 {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "If specified, looks for txid in the block with this hash"},
39 },
40 RPCResult{
41 RPCResult::Type::STR, "data", "A string that is a serialized, hex-encoded data for the proof."
42 },
43 RPCExamples{""},
44 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
45 {
46 std::set<Txid> setTxids;
47 UniValue txids = request.params[0].get_array();
48 if (txids.empty()) {
49 throw JSONRPCError(RPC_INVALID_PARAMETER, "Parameter 'txids' cannot be empty");
50 }
51 for (unsigned int idx = 0; idx < txids.size(); idx++) {
52 auto ret{setTxids.insert(Txid::FromUint256(ParseHashV(txids[idx], "txid")))};
53 if (!ret.second) {
54 throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated txid: ") + txids[idx].get_str());
55 }
56 }
57
58 const CBlockIndex* pblockindex = nullptr;
59 uint256 hashBlock;
60 ChainstateManager& chainman = EnsureAnyChainman(request.context);
61 if (!request.params[1].isNull()) {
62 LOCK(cs_main);
63 hashBlock = ParseHashV(request.params[1], "blockhash");
64 pblockindex = chainman.m_blockman.LookupBlockIndex(hashBlock);
65 if (!pblockindex) {
66 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
67 }
68 } else {
69 LOCK(cs_main);
70 Chainstate& active_chainstate = chainman.ActiveChainstate();
71
72 // Loop through txids and try to find which block they're in. Exit loop once a block is found.
73 for (const auto& tx : setTxids) {
74 const Coin& coin{AccessByTxid(active_chainstate.CoinsTip(), tx)};
75 if (!coin.IsSpent()) {
76 pblockindex = active_chainstate.m_chain[coin.nHeight];
77 break;
78 }
79 }
80 }

Callers

nothing calls this directly

Calls 15

JSONRPCErrorFunction · 0.85
ParseHashVFunction · 0.85
GetTransactionFunction · 0.85
isNullMethod · 0.80
LookupBlockIndexMethod · 0.80
HexStrFunction · 0.50
emptyMethod · 0.45
sizeMethod · 0.45
insertMethod · 0.45
IsSpentMethod · 0.45

Tested by

no test coverage detected