MCPcopy Create free account
hub / github.com/ElementsProject/elements / gettxoutproof

Function gettxoutproof

src/rpc/rawtransaction.cpp:311–410  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

309}
310
311static RPCHelpMan gettxoutproof()
312{
313 return RPCHelpMan{"gettxoutproof",
314 "\nReturns a hex-encoded proof that \"txid\" was included in a block.\n"
315 "\nNOTE: By default this function only works sometimes. This is when there is an\n"
316 "unspent output in the utxo for this transaction. To make it always work,\n"
317 "you need to maintain a transaction index, using the -txindex command line option or\n"
318 "specify the block in which the transaction is included manually (by blockhash).\n",
319 {
320 {"txids", RPCArg::Type::ARR, RPCArg::Optional::NO, "The txids to filter",
321 {
322 {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "A transaction hash"},
323 },
324 },
325 {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED_NAMED_ARG, "If specified, looks for txid in the block with this hash"},
326 },
327 RPCResult{
328 RPCResult::Type::STR, "data", "A string that is a serialized, hex-encoded data for the proof."
329 },
330 RPCExamples{""},
331 [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
332{
333 std::set<uint256> setTxids;
334 UniValue txids = request.params[0].get_array();
335 if (txids.empty()) {
336 throw JSONRPCError(RPC_INVALID_PARAMETER, "Parameter 'txids' cannot be empty");
337 }
338 for (unsigned int idx = 0; idx < txids.size(); idx++) {
339 auto ret = setTxids.insert(ParseHashV(txids[idx], "txid"));
340 if (!ret.second) {
341 throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated txid: ") + txids[idx].get_str());
342 }
343 }
344
345 CBlockIndex* pblockindex = nullptr;
346 uint256 hashBlock;
347 ChainstateManager& chainman = EnsureAnyChainman(request.context);
348 if (!request.params[1].isNull()) {
349 LOCK(cs_main);
350 hashBlock = ParseHashV(request.params[1], "blockhash");
351 pblockindex = chainman.m_blockman.LookupBlockIndex(hashBlock);
352 if (!pblockindex) {
353 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
354 }
355 } else {
356 LOCK(cs_main);
357 CChainState& active_chainstate = chainman.ActiveChainstate();
358
359 // Loop through txids and try to find which block they're in. Exit loop once a block is found.
360 for (const auto& tx : setTxids) {
361 const Coin& coin = AccessByTxid(active_chainstate.CoinsTip(), tx);
362 if (!coin.IsSpent()) {
363 pblockindex = active_chainstate.m_chain[coin.nHeight];
364 break;
365 }
366 }
367 }
368

Callers

nothing calls this directly

Calls 15

JSONRPCErrorFunction · 0.85
ParseHashVFunction · 0.85
GetTransactionFunction · 0.85
ReadBlockFromDiskFunction · 0.85
LookupBlockIndexMethod · 0.80
countMethod · 0.80
ParamsClass · 0.50
HexStrFunction · 0.50
emptyMethod · 0.45
sizeMethod · 0.45
insertMethod · 0.45
isNullMethod · 0.45

Tested by

no test coverage detected