Bitcoin ABC 0.32.4
P2P Digital Currency
rawtransaction.cpp
Go to the documentation of this file.
1// Copyright (c) 2010 Satoshi Nakamoto
2// Copyright (c) 2009-2016 The Bitcoin Core developers
3// Distributed under the MIT software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#include <chain.h>
7#include <chainparams.h>
8#include <coins.h>
9#include <config.h>
10#include <consensus/amount.h>
12#include <core_io.h>
13#include <index/txindex.h>
14#include <key_io.h>
15#include <node/blockstorage.h>
16#include <node/coin.h>
17#include <node/context.h>
18#include <node/psbt.h>
19#include <node/transaction.h>
20#include <policy/packages.h>
21#include <policy/policy.h>
23#include <psbt.h>
24#include <random.h>
25#include <rpc/blockchain.h>
27#include <rpc/server.h>
28#include <rpc/server_util.h>
29#include <rpc/util.h>
30#include <script/script.h>
31#include <script/sign.h>
33#include <script/standard.h>
34#include <txmempool.h>
35#include <uint256.h>
36#include <util/bip32.h>
37#include <util/check.h>
38#include <util/error.h>
39#include <util/strencodings.h>
40#include <util/string.h>
41#include <validation.h>
42#include <validationinterface.h>
43
44#include <cstdint>
45#include <numeric>
46
47#include <univalue.h>
48
50using node::FindCoins;
54
55static void TxToJSON(const CTransaction &tx, const BlockHash &hashBlock,
56 UniValue &entry, Chainstate &active_chainstate) {
57 // Call into TxToUniv() in bitcoin-common to decode the transaction hex.
58 //
59 // Blockchain contextual information (confirmations and blocktime) is not
60 // available to code in bitcoin-common, so we query them here and push the
61 // data into the returned UniValue.
62 TxToUniv(tx, BlockHash(), entry, true);
63
64 if (!hashBlock.IsNull()) {
66
67 entry.pushKV("blockhash", hashBlock.GetHex());
68 const CBlockIndex *pindex =
69 active_chainstate.m_blockman.LookupBlockIndex(hashBlock);
70 if (pindex) {
71 if (active_chainstate.m_chain.Contains(pindex)) {
72 entry.pushKV("confirmations",
73 1 + active_chainstate.m_chain.Height() -
74 pindex->nHeight);
75 entry.pushKV("time", pindex->GetBlockTime());
76 entry.pushKV("blocktime", pindex->GetBlockTime());
77 } else {
78 entry.pushKV("confirmations", 0);
79 }
80 }
81 }
82}
83
85 return RPCHelpMan{
86 "getrawtransaction",
87 "\nReturn the raw transaction data.\n"
88 "\nBy default, this call only returns a transaction if it is in the "
89 "mempool. If -txindex is enabled\n"
90 "and no blockhash argument is passed, it will return the transaction "
91 "if it is in the mempool or any block.\n"
92 "If a blockhash argument is passed, it will return the transaction if\n"
93 "the specified block is available and the transaction is in that "
94 "block.\n"
95 "\nIf verbose is 'true', returns an Object with information about "
96 "'txid'.\n"
97 "If verbose is 'false' or omitted, returns a string that is "
98 "serialized, hex-encoded data for 'txid'.\n",
99 {
101 "The transaction id"},
102 // Verbose is a boolean, but we accept an int for backward
103 // compatibility
104 {"verbose", RPCArg::Type::BOOL, RPCArg::Default{false},
105 "If false, return a string, otherwise return a json object",
108 "The block in which to look for the transaction"},
109 },
110 {
111 RPCResult{"if verbose is not set or set to false",
112 RPCResult::Type::STR, "data",
113 "The serialized, hex-encoded data for 'txid'"},
114 RPCResult{
115 "if verbose is set to true",
117 "",
118 "",
119 {
120 {RPCResult::Type::BOOL, "in_active_chain",
121 "Whether specified block is in the active chain or not "
122 "(only present with explicit \"blockhash\" argument)"},
124 "The serialized, hex-encoded data for 'txid'"},
126 "The transaction id (same as provided)"},
127 {RPCResult::Type::STR_HEX, "hash", "The transaction hash"},
128 {RPCResult::Type::NUM, "size",
129 "The serialized transaction size"},
130 {RPCResult::Type::NUM, "version", "The version"},
131 {RPCResult::Type::NUM_TIME, "locktime", "The lock time"},
133 "vin",
134 "",
135 {
137 "",
138 "",
139 {
141 "The transaction id"},
142 {RPCResult::Type::STR, "vout", ""},
144 "scriptSig",
145 "The script",
146 {
147 {RPCResult::Type::STR, "asm", "asm"},
148 {RPCResult::Type::STR_HEX, "hex", "hex"},
149 }},
150 {RPCResult::Type::NUM, "sequence",
151 "The script sequence number"},
152 }},
153 }},
155 "vout",
156 "",
157 {
159 "",
160 "",
161 {
162 {RPCResult::Type::NUM, "value",
163 "The value in " + Currency::get().ticker},
164 {RPCResult::Type::NUM, "n", "index"},
166 "scriptPubKey",
167 "",
168 {
169 {RPCResult::Type::STR, "asm", "the asm"},
170 {RPCResult::Type::STR, "hex", "the hex"},
171 {RPCResult::Type::NUM, "reqSigs",
172 "The required sigs"},
173 {RPCResult::Type::STR, "type",
174 "The type, eg 'pubkeyhash'"},
176 "addresses",
177 "",
178 {
179 {RPCResult::Type::STR, "address",
180 "bitcoin address"},
181 }},
182 }},
183 }},
184 }},
185 {RPCResult::Type::STR_HEX, "blockhash", "the block hash"},
186 {RPCResult::Type::NUM, "confirmations",
187 "The confirmations"},
188 {RPCResult::Type::NUM_TIME, "blocktime",
189 "The block time expressed in " + UNIX_EPOCH_TIME},
190 {RPCResult::Type::NUM, "time", "Same as \"blocktime\""},
191 }},
192 },
193 RPCExamples{HelpExampleCli("getrawtransaction", "\"mytxid\"") +
194 HelpExampleCli("getrawtransaction", "\"mytxid\" true") +
195 HelpExampleRpc("getrawtransaction", "\"mytxid\", true") +
196 HelpExampleCli("getrawtransaction",
197 "\"mytxid\" false \"myblockhash\"") +
198 HelpExampleCli("getrawtransaction",
199 "\"mytxid\" true \"myblockhash\"")},
200 [&](const RPCHelpMan &self, const Config &config,
201 const JSONRPCRequest &request) -> UniValue {
202 const NodeContext &node = EnsureAnyNodeContext(request.context);
204
205 bool in_active_chain = true;
206 TxId txid = TxId(ParseHashV(request.params[0], "parameter 1"));
207 const CBlockIndex *blockindex = nullptr;
208
209 const CChainParams &params = config.GetChainParams();
210 if (txid == params.GenesisBlock().hashMerkleRoot) {
211 // Special exception for the genesis block coinbase transaction
212 throw JSONRPCError(
214 "The genesis block coinbase is not considered an "
215 "ordinary transaction and cannot be retrieved");
216 }
217
218 // Accept either a bool (true) or a num (>=1) to indicate verbose
219 // output.
220 bool fVerbose = false;
221 if (!request.params[1].isNull()) {
222 fVerbose = request.params[1].isNum()
223 ? (request.params[1].getInt<int>() != 0)
224 : request.params[1].get_bool();
225 }
226
227 if (!request.params[2].isNull()) {
228 LOCK(cs_main);
229
230 BlockHash blockhash(
231 ParseHashV(request.params[2], "parameter 3"));
232 blockindex = chainman.m_blockman.LookupBlockIndex(blockhash);
233 if (!blockindex) {
235 "Block hash not found");
236 }
237 in_active_chain = chainman.ActiveChain().Contains(blockindex);
238 }
239
240 bool f_txindex_ready = false;
241 if (g_txindex && !blockindex) {
242 f_txindex_ready = g_txindex->BlockUntilSyncedToCurrentChain();
243 }
244
245 BlockHash hash_block;
246 const CTransactionRef tx =
247 GetTransaction(blockindex, node.mempool.get(), txid, hash_block,
248 chainman.m_blockman);
249 if (!tx) {
250 std::string errmsg;
251 if (blockindex) {
253 return !blockindex->nStatus.hasData())) {
255 "Block not available");
256 }
257 errmsg = "No such transaction found in the provided block";
258 } else if (!g_txindex) {
259 errmsg =
260 "No such mempool transaction. Use -txindex or provide "
261 "a block hash to enable blockchain transaction queries";
262 } else if (!f_txindex_ready) {
263 errmsg = "No such mempool transaction. Blockchain "
264 "transactions are still in the process of being "
265 "indexed";
266 } else {
267 errmsg = "No such mempool or blockchain transaction";
268 }
269 throw JSONRPCError(
271 errmsg + ". Use gettransaction for wallet transactions.");
272 }
273
274 if (!fVerbose) {
275 return EncodeHexTx(*tx);
276 }
277
278 UniValue result(UniValue::VOBJ);
279 if (blockindex) {
280 result.pushKV("in_active_chain", in_active_chain);
281 }
282 TxToJSON(*tx, hash_block, result, chainman.ActiveChainstate());
283 return result;
284 },
285 };
286}
287
289 return RPCHelpMan{
290 "createrawtransaction",
291 "Create a transaction spending the given inputs and creating new "
292 "outputs.\n"
293 "Outputs can be addresses or data.\n"
294 "Returns hex-encoded raw transaction.\n"
295 "Note that the transaction's inputs are not signed, and\n"
296 "it is not stored in the wallet or transmitted to the network.\n",
297 {
298 {
299 "inputs",
302 "The inputs",
303 {
304 {
305 "",
308 "",
309 {
310 {"txid", RPCArg::Type::STR_HEX,
311 RPCArg::Optional::NO, "The transaction id"},
313 "The output number"},
314 {"sequence", RPCArg::Type::NUM,
315 RPCArg::DefaultHint{"depends on the value of the "
316 "'locktime' argument"},
317 "The sequence number"},
318 },
319 },
320 },
321 },
322 {"outputs",
325 "The outputs (key-value pairs), where none of "
326 "the keys are duplicated.\n"
327 "That is, each address can only appear once and there can only "
328 "be one 'data' object.\n"
329 "For compatibility reasons, a dictionary, which holds the "
330 "key-value pairs directly, is also\n"
331 " accepted as second parameter.",
332 {
333 {
334 "",
337 "",
338 {
340 "A key-value pair. The key (string) is the "
341 "bitcoin address, the value (float or string) is "
342 "the amount in " +
344 },
345 },
346 {
347 "",
350 "",
351 {
353 "A key-value pair. The key must be \"data\", the "
354 "value is hex-encoded data"},
355 },
356 },
357 },
359 {"locktime", RPCArg::Type::NUM, RPCArg::Default{0},
360 "Raw locktime. Non-0 value also locktime-activates inputs"},
361 },
362 RPCResult{RPCResult::Type::STR_HEX, "transaction",
363 "hex string of the transaction"},
365 HelpExampleCli("createrawtransaction",
366 "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
367 "\" \"[{\\\"address\\\":10000.00}]\"") +
368 HelpExampleCli("createrawtransaction",
369 "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
370 "\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") +
371 HelpExampleRpc("createrawtransaction",
372 "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
373 "\", \"[{\\\"address\\\":10000.00}]\"") +
374 HelpExampleRpc("createrawtransaction",
375 "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
376 "\", \"[{\\\"data\\\":\\\"00010203\\\"}]\"")},
377 [&](const RPCHelpMan &self, const Config &config,
378 const JSONRPCRequest &request) -> UniValue {
379 CMutableTransaction rawTx =
380 ConstructTransaction(config.GetChainParams(), request.params[0],
381 request.params[1], request.params[2]);
382
383 return EncodeHexTx(CTransaction(rawTx));
384 },
385 };
386}
387
389 return RPCHelpMan{
390 "decoderawtransaction",
391 "Return a JSON object representing the serialized, hex-encoded "
392 "transaction.\n",
393 {
395 "The transaction hex string"},
396 },
397 RPCResult{
399 "",
400 "",
401 {
402 {RPCResult::Type::STR_HEX, "txid", "The transaction id"},
403 {RPCResult::Type::STR_HEX, "hash", "The transaction hash"},
404 {RPCResult::Type::NUM, "size", "The transaction size"},
405 {RPCResult::Type::NUM, "version", "The version"},
406 {RPCResult::Type::NUM_TIME, "locktime", "The lock time"},
408 "vin",
409 "",
410 {
412 "",
413 "",
414 {
416 "The transaction id"},
417 {RPCResult::Type::NUM, "vout", "The output number"},
419 "scriptSig",
420 "The script",
421 {
422 {RPCResult::Type::STR, "asm", "asm"},
423 {RPCResult::Type::STR_HEX, "hex", "hex"},
424 }},
425 {RPCResult::Type::NUM, "sequence",
426 "The script sequence number"},
427 }},
428 }},
430 "vout",
431 "",
432 {
434 "",
435 "",
436 {
437 {RPCResult::Type::NUM, "value",
438 "The value in " + Currency::get().ticker},
439 {RPCResult::Type::NUM, "n", "index"},
441 "scriptPubKey",
442 "",
443 {
444 {RPCResult::Type::STR, "asm", "the asm"},
445 {RPCResult::Type::STR_HEX, "hex", "the hex"},
446 {RPCResult::Type::NUM, "reqSigs",
447 "The required sigs"},
448 {RPCResult::Type::STR, "type",
449 "The type, eg 'pubkeyhash'"},
451 "addresses",
452 "",
453 {
454 {RPCResult::Type::STR, "address",
455 "bitcoin address"},
456 }},
457 }},
458 }},
459 }},
460 }},
461 RPCExamples{HelpExampleCli("decoderawtransaction", "\"hexstring\"") +
462 HelpExampleRpc("decoderawtransaction", "\"hexstring\"")},
463 [&](const RPCHelpMan &self, const Config &config,
464 const JSONRPCRequest &request) -> UniValue {
466
467 if (!DecodeHexTx(mtx, request.params[0].get_str())) {
469 "TX decode failed");
470 }
471
472 UniValue result(UniValue::VOBJ);
473 TxToUniv(CTransaction(std::move(mtx)), BlockHash(), result, false);
474
475 return result;
476 },
477 };
478}
479
481 return RPCHelpMan{
482 "decodescript",
483 "Decode a hex-encoded script.\n",
484 {
486 "the hex-encoded script"},
487 },
488 RPCResult{
490 "",
491 "",
492 {
493 {RPCResult::Type::STR, "asm", "Script public key"},
494 {RPCResult::Type::STR, "type",
495 "The output type (e.g. " + GetAllOutputTypes() + ")"},
496 {RPCResult::Type::NUM, "reqSigs", "The required signatures"},
498 "addresses",
499 "",
500 {
501 {RPCResult::Type::STR, "address", "bitcoin address"},
502 }},
503 {RPCResult::Type::STR, "p2sh",
504 "address of P2SH script wrapping this redeem script (not "
505 "returned if the script is already a P2SH)"},
506 }},
507 RPCExamples{HelpExampleCli("decodescript", "\"hexstring\"") +
508 HelpExampleRpc("decodescript", "\"hexstring\"")},
509 [&](const RPCHelpMan &self, const Config &config,
510 const JSONRPCRequest &request) -> UniValue {
512 CScript script;
513 if (request.params[0].get_str().size() > 0) {
514 std::vector<uint8_t> scriptData(
515 ParseHexV(request.params[0], "argument"));
516 script = CScript(scriptData.begin(), scriptData.end());
517 } else {
518 // Empty scripts are valid.
519 }
520
521 ScriptPubKeyToUniv(script, r, /* fIncludeHex */ false);
522
523 UniValue type;
524 type = r.find_value("type");
525
526 if (type.isStr() && type.get_str() != "scripthash") {
527 // P2SH cannot be wrapped in a P2SH. If this script is already a
528 // P2SH, don't return the address for a P2SH of the P2SH.
529 r.pushKV("p2sh", EncodeDestination(ScriptHash(script), config));
530 }
531
532 return r;
533 },
534 };
535}
536
538 return RPCHelpMan{
539 "combinerawtransaction",
540 "Combine multiple partially signed transactions into one "
541 "transaction.\n"
542 "The combined transaction may be another partially signed transaction "
543 "or a \n"
544 "fully signed transaction.",
545 {
546 {
547 "txs",
550 "The hex strings of partially signed "
551 "transactions",
552 {
553 {"hexstring", RPCArg::Type::STR_HEX,
555 "A hex-encoded raw transaction"},
556 },
557 },
558 },
560 "The hex-encoded raw transaction with signature(s)"},
561 RPCExamples{HelpExampleCli("combinerawtransaction",
562 R"('["myhex1", "myhex2", "myhex3"]')")},
563 [&](const RPCHelpMan &self, const Config &config,
564 const JSONRPCRequest &request) -> UniValue {
565 UniValue txs = request.params[0].get_array();
566 std::vector<CMutableTransaction> txVariants(txs.size());
567
568 for (unsigned int idx = 0; idx < txs.size(); idx++) {
569 if (!DecodeHexTx(txVariants[idx], txs[idx].get_str())) {
570 throw JSONRPCError(
572 strprintf("TX decode failed for tx %d", idx));
573 }
574 }
575
576 if (txVariants.empty()) {
578 "Missing transactions");
579 }
580
581 // mergedTx will end up with all the signatures; it
582 // starts as a clone of the rawtx:
583 CMutableTransaction mergedTx(txVariants[0]);
584
585 // Fetch previous transactions (inputs):
586 CCoinsView viewDummy;
587 CCoinsViewCache view(&viewDummy);
588 {
589 NodeContext &node = EnsureAnyNodeContext(request.context);
590 const CTxMemPool &mempool = EnsureMemPool(node);
592 LOCK2(cs_main, mempool.cs);
593 CCoinsViewCache &viewChain =
594 chainman.ActiveChainstate().CoinsTip();
595 CCoinsViewMemPool viewMempool(&viewChain, mempool);
596 // temporarily switch cache backend to db+mempool view
597 view.SetBackend(viewMempool);
598
599 for (const CTxIn &txin : mergedTx.vin) {
600 // Load entries from viewChain into view; can fail.
601 view.AccessCoin(txin.prevout);
602 }
603
604 // switch back to avoid locking mempool for too long
605 view.SetBackend(viewDummy);
606 }
607
608 // Use CTransaction for the constant parts of the
609 // transaction to avoid rehashing.
610 const CTransaction txConst(mergedTx);
611 // Sign what we can:
612 for (size_t i = 0; i < mergedTx.vin.size(); i++) {
613 CTxIn &txin = mergedTx.vin[i];
614 const Coin &coin = view.AccessCoin(txin.prevout);
615 if (coin.IsSpent()) {
617 "Input not found or already spent");
618 }
619 SignatureData sigdata;
620
621 const CTxOut &txout = coin.GetTxOut();
622
623 // ... and merge in other signatures:
624 for (const CMutableTransaction &txv : txVariants) {
625 if (txv.vin.size() > i) {
626 sigdata.MergeSignatureData(
627 DataFromTransaction(txv, i, txout));
628 }
629 }
632 &mergedTx, i, txout.nValue),
633 txout.scriptPubKey, sigdata);
634
635 UpdateInput(txin, sigdata);
636 }
637
638 return EncodeHexTx(CTransaction(mergedTx));
639 },
640 };
641}
642
644 return RPCHelpMan{
645 "signrawtransactionwithkey",
646 "Sign inputs for raw transaction (serialized, hex-encoded).\n"
647 "The second argument is an array of base58-encoded private\n"
648 "keys that will be the only keys used to sign the transaction.\n"
649 "The third optional argument (may be null) is an array of previous "
650 "transaction outputs that\n"
651 "this transaction depends on but may not yet be in the block chain.\n",
652 {
654 "The transaction hex string"},
655 {
656 "privkeys",
659 "The base58-encoded private keys for signing",
660 {
662 "private key in base58-encoding"},
663 },
664 },
665 {
666 "prevtxs",
669 "The previous dependent transaction outputs",
670 {
671 {
672 "",
675 "",
676 {
677 {"txid", RPCArg::Type::STR_HEX,
678 RPCArg::Optional::NO, "The transaction id"},
680 "The output number"},
681 {"scriptPubKey", RPCArg::Type::STR_HEX,
682 RPCArg::Optional::NO, "script key"},
683 {"redeemScript", RPCArg::Type::STR_HEX,
685 "(required for P2SH) redeem script"},
686 {"amount", RPCArg::Type::AMOUNT,
687 RPCArg::Optional::NO, "The amount spent"},
688 },
689 },
690 },
691 },
692 {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"ALL|FORKID"},
693 "The signature hash type. Must be one of:\n"
694 " \"ALL|FORKID\"\n"
695 " \"NONE|FORKID\"\n"
696 " \"SINGLE|FORKID\"\n"
697 " \"ALL|FORKID|ANYONECANPAY\"\n"
698 " \"NONE|FORKID|ANYONECANPAY\"\n"
699 " \"SINGLE|FORKID|ANYONECANPAY\""},
700 },
701 RPCResult{
703 "",
704 "",
705 {
707 "The hex-encoded raw transaction with signature(s)"},
708 {RPCResult::Type::BOOL, "complete",
709 "If the transaction has a complete set of signatures"},
711 "errors",
712 /* optional */ true,
713 "Script verification errors (if there are any)",
714 {
716 "",
717 "",
718 {
720 "The hash of the referenced, previous transaction"},
721 {RPCResult::Type::NUM, "vout",
722 "The index of the output to spent and used as "
723 "input"},
724 {RPCResult::Type::STR_HEX, "scriptSig",
725 "The hex-encoded signature script"},
726 {RPCResult::Type::NUM, "sequence",
727 "Script sequence number"},
728 {RPCResult::Type::STR, "error",
729 "Verification or signing error related to the "
730 "input"},
731 }},
732 }},
733 }},
735 HelpExampleCli("signrawtransactionwithkey",
736 "\"myhex\" \"[\\\"key1\\\",\\\"key2\\\"]\"") +
737 HelpExampleRpc("signrawtransactionwithkey",
738 "\"myhex\", \"[\\\"key1\\\",\\\"key2\\\"]\"")},
739 [&](const RPCHelpMan &self, const Config &config,
740 const JSONRPCRequest &request) -> UniValue {
742 if (!DecodeHexTx(mtx, request.params[0].get_str())) {
744 "TX decode failed");
745 }
746
748 const UniValue &keys = request.params[1].get_array();
749 for (size_t idx = 0; idx < keys.size(); ++idx) {
750 UniValue k = keys[idx];
751 CKey key = DecodeSecret(k.get_str());
752 if (!key.IsValid()) {
754 "Invalid private key");
755 }
756 keystore.AddKey(key);
757 }
758
759 // Fetch previous transactions (inputs):
760 std::map<COutPoint, Coin> coins;
761 for (const CTxIn &txin : mtx.vin) {
762 // Create empty map entry keyed by prevout.
763 coins[txin.prevout];
764 }
765 NodeContext &node = EnsureAnyNodeContext(request.context);
766 FindCoins(node, coins);
767
768 // Parse the prevtxs array
769 ParsePrevouts(request.params[2], &keystore, coins);
770
771 UniValue result(UniValue::VOBJ);
772 SignTransaction(mtx, &keystore, coins, request.params[3], result);
773 return result;
774 },
775 };
776}
777
779 return RPCHelpMan{
780 "decodepsbt",
781 "Return a JSON object representing the serialized, base64-encoded "
782 "partially signed Bitcoin transaction.\n",
783 {
785 "The PSBT base64 string"},
786 },
787 RPCResult{
789 "",
790 "",
791 {
793 "tx",
794 "The decoded network-serialized unsigned transaction.",
795 {
797 "The layout is the same as the output of "
798 "decoderawtransaction."},
799 }},
801 "unknown",
802 "The unknown global fields",
803 {
805 "(key-value pair) An unknown key-value pair"},
806 }},
808 "inputs",
809 "",
810 {
812 "",
813 "",
814 {
816 "utxo",
817 /* optional */ true,
818 "Transaction output for UTXOs",
819 {
820 {RPCResult::Type::NUM, "amount",
821 "The value in " + Currency::get().ticker},
823 "scriptPubKey",
824 "",
825 {
826 {RPCResult::Type::STR, "asm", "The asm"},
828 "The hex"},
829 {RPCResult::Type::STR, "type",
830 "The type, eg 'pubkeyhash'"},
831 {RPCResult::Type::STR, "address",
832 " Bitcoin address if there is one"},
833 }},
834 }},
836 "partial_signatures",
837 /* optional */ true,
838 "",
839 {
840 {RPCResult::Type::STR, "pubkey",
841 "The public key and signature that corresponds "
842 "to it."},
843 }},
844 {RPCResult::Type::STR, "sighash", /* optional */ true,
845 "The sighash type to be used"},
847 "redeem_script",
848 /* optional */ true,
849 "",
850 {
851 {RPCResult::Type::STR, "asm", "The asm"},
852 {RPCResult::Type::STR_HEX, "hex", "The hex"},
853 {RPCResult::Type::STR, "type",
854 "The type, eg 'pubkeyhash'"},
855 }},
857 "bip32_derivs",
858 /* optional */ true,
859 "",
860 {
862 "pubkey",
863 /* optional */ true,
864 "The public key with the derivation path as "
865 "the value.",
866 {
867 {RPCResult::Type::STR, "master_fingerprint",
868 "The fingerprint of the master key"},
869 {RPCResult::Type::STR, "path", "The path"},
870 }},
871 }},
873 "final_scriptsig",
874 /* optional */ true,
875 "",
876 {
877 {RPCResult::Type::STR, "asm", "The asm"},
878 {RPCResult::Type::STR, "hex", "The hex"},
879 }},
881 "unknown",
882 "The unknown global fields",
883 {
885 "(key-value pair) An unknown key-value pair"},
886 }},
887 }},
888 }},
890 "outputs",
891 "",
892 {
894 "",
895 "",
896 {
898 "redeem_script",
899 /* optional */ true,
900 "",
901 {
902 {RPCResult::Type::STR, "asm", "The asm"},
903 {RPCResult::Type::STR_HEX, "hex", "The hex"},
904 {RPCResult::Type::STR, "type",
905 "The type, eg 'pubkeyhash'"},
906 }},
908 "bip32_derivs",
909 /* optional */ true,
910 "",
911 {
913 "",
914 "",
915 {
916 {RPCResult::Type::STR, "pubkey",
917 "The public key this path corresponds to"},
918 {RPCResult::Type::STR, "master_fingerprint",
919 "The fingerprint of the master key"},
920 {RPCResult::Type::STR, "path", "The path"},
921 }},
922 }},
924 "unknown",
925 "The unknown global fields",
926 {
928 "(key-value pair) An unknown key-value pair"},
929 }},
930 }},
931 }},
932 {RPCResult::Type::STR_AMOUNT, "fee", /* optional */ true,
933 "The transaction fee paid if all UTXOs slots in the PSBT have "
934 "been filled."},
935 }},
936 RPCExamples{HelpExampleCli("decodepsbt", "\"psbt\"")},
937 [&](const RPCHelpMan &self, const Config &config,
938 const JSONRPCRequest &request) -> UniValue {
939 // Unserialize the transactions
941 std::string error;
942 if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
944 strprintf("TX decode failed %s", error));
945 }
946
947 UniValue result(UniValue::VOBJ);
948
949 // Add the decoded tx
950 UniValue tx_univ(UniValue::VOBJ);
951 TxToUniv(CTransaction(*psbtx.tx), BlockHash(), tx_univ, false);
952 result.pushKV("tx", tx_univ);
953
954 // Unknown data
955 if (psbtx.unknown.size() > 0) {
956 UniValue unknowns(UniValue::VOBJ);
957 for (auto entry : psbtx.unknown) {
958 unknowns.pushKV(HexStr(entry.first), HexStr(entry.second));
959 }
960 result.pushKV("unknown", unknowns);
961 }
962
963 // inputs
964 Amount total_in = Amount::zero();
965 bool have_all_utxos = true;
966 UniValue inputs(UniValue::VARR);
967 for (size_t i = 0; i < psbtx.inputs.size(); ++i) {
968 const PSBTInput &input = psbtx.inputs[i];
970 // UTXOs
971 if (!input.utxo.IsNull()) {
972 const CTxOut &txout = input.utxo;
973
975
976 out.pushKV("amount", txout.nValue);
977 if (MoneyRange(txout.nValue) &&
978 MoneyRange(total_in + txout.nValue)) {
979 total_in += txout.nValue;
980 } else {
981 // Hack to just not show fee later
982 have_all_utxos = false;
983 }
984
986 ScriptToUniv(txout.scriptPubKey, o, true);
987 out.pushKV("scriptPubKey", o);
988 in.pushKV("utxo", out);
989 } else {
990 have_all_utxos = false;
991 }
992
993 // Partial sigs
994 if (!input.partial_sigs.empty()) {
995 UniValue partial_sigs(UniValue::VOBJ);
996 for (const auto &sig : input.partial_sigs) {
997 partial_sigs.pushKV(HexStr(sig.second.first),
998 HexStr(sig.second.second));
999 }
1000 in.pushKV("partial_signatures", partial_sigs);
1001 }
1002
1003 // Sighash
1004 uint8_t sighashbyte =
1005 input.sighash_type.getRawSigHashType() & 0xff;
1006 if (sighashbyte > 0) {
1007 in.pushKV("sighash", SighashToStr(sighashbyte));
1008 }
1009
1010 // Redeem script
1011 if (!input.redeem_script.empty()) {
1013 ScriptToUniv(input.redeem_script, r, false);
1014 in.pushKV("redeem_script", r);
1015 }
1016
1017 // keypaths
1018 if (!input.hd_keypaths.empty()) {
1019 UniValue keypaths(UniValue::VARR);
1020 for (auto entry : input.hd_keypaths) {
1021 UniValue keypath(UniValue::VOBJ);
1022 keypath.pushKV("pubkey", HexStr(entry.first));
1023
1024 keypath.pushKV(
1025 "master_fingerprint",
1026 strprintf("%08x",
1027 ReadBE32(entry.second.fingerprint)));
1028 keypath.pushKV("path",
1029 WriteHDKeypath(entry.second.path));
1030 keypaths.push_back(keypath);
1031 }
1032 in.pushKV("bip32_derivs", keypaths);
1033 }
1034
1035 // Final scriptSig
1036 if (!input.final_script_sig.empty()) {
1037 UniValue scriptsig(UniValue::VOBJ);
1038 scriptsig.pushKV(
1039 "asm", ScriptToAsmStr(input.final_script_sig, true));
1040 scriptsig.pushKV("hex", HexStr(input.final_script_sig));
1041 in.pushKV("final_scriptSig", scriptsig);
1042 }
1043
1044 // Unknown data
1045 if (input.unknown.size() > 0) {
1046 UniValue unknowns(UniValue::VOBJ);
1047 for (auto entry : input.unknown) {
1048 unknowns.pushKV(HexStr(entry.first),
1049 HexStr(entry.second));
1050 }
1051 in.pushKV("unknown", unknowns);
1052 }
1053
1054 inputs.push_back(in);
1055 }
1056 result.pushKV("inputs", inputs);
1057
1058 // outputs
1059 Amount output_value = Amount::zero();
1060 UniValue outputs(UniValue::VARR);
1061 for (size_t i = 0; i < psbtx.outputs.size(); ++i) {
1062 const PSBTOutput &output = psbtx.outputs[i];
1064 // Redeem script
1065 if (!output.redeem_script.empty()) {
1067 ScriptToUniv(output.redeem_script, r, false);
1068 out.pushKV("redeem_script", r);
1069 }
1070
1071 // keypaths
1072 if (!output.hd_keypaths.empty()) {
1073 UniValue keypaths(UniValue::VARR);
1074 for (auto entry : output.hd_keypaths) {
1075 UniValue keypath(UniValue::VOBJ);
1076 keypath.pushKV("pubkey", HexStr(entry.first));
1077 keypath.pushKV(
1078 "master_fingerprint",
1079 strprintf("%08x",
1080 ReadBE32(entry.second.fingerprint)));
1081 keypath.pushKV("path",
1082 WriteHDKeypath(entry.second.path));
1083 keypaths.push_back(keypath);
1084 }
1085 out.pushKV("bip32_derivs", keypaths);
1086 }
1087
1088 // Unknown data
1089 if (output.unknown.size() > 0) {
1090 UniValue unknowns(UniValue::VOBJ);
1091 for (auto entry : output.unknown) {
1092 unknowns.pushKV(HexStr(entry.first),
1093 HexStr(entry.second));
1094 }
1095 out.pushKV("unknown", unknowns);
1096 }
1097
1098 outputs.push_back(out);
1099
1100 // Fee calculation
1101 if (MoneyRange(psbtx.tx->vout[i].nValue) &&
1102 MoneyRange(output_value + psbtx.tx->vout[i].nValue)) {
1103 output_value += psbtx.tx->vout[i].nValue;
1104 } else {
1105 // Hack to just not show fee later
1106 have_all_utxos = false;
1107 }
1108 }
1109 result.pushKV("outputs", outputs);
1110 if (have_all_utxos) {
1111 result.pushKV("fee", total_in - output_value);
1112 }
1113
1114 return result;
1115 },
1116 };
1117}
1118
1120 return RPCHelpMan{
1121 "combinepsbt",
1122 "Combine multiple partially signed Bitcoin transactions into one "
1123 "transaction.\n"
1124 "Implements the Combiner role.\n",
1125 {
1126 {
1127 "txs",
1130 "The base64 strings of partially signed transactions",
1131 {
1133 "A base64 string of a PSBT"},
1134 },
1135 },
1136 },
1138 "The base64-encoded partially signed transaction"},
1140 "combinepsbt", R"('["mybase64_1", "mybase64_2", "mybase64_3"]')")},
1141 [&](const RPCHelpMan &self, const Config &config,
1142 const JSONRPCRequest &request) -> UniValue {
1143 // Unserialize the transactions
1144 std::vector<PartiallySignedTransaction> psbtxs;
1145 UniValue txs = request.params[0].get_array();
1146 if (txs.empty()) {
1148 "Parameter 'txs' cannot be empty");
1149 }
1150 for (size_t i = 0; i < txs.size(); ++i) {
1152 std::string error;
1153 if (!DecodeBase64PSBT(psbtx, txs[i].get_str(), error)) {
1155 strprintf("TX decode failed %s", error));
1156 }
1157 psbtxs.push_back(psbtx);
1158 }
1159
1160 PartiallySignedTransaction merged_psbt;
1161 const TransactionError error = CombinePSBTs(merged_psbt, psbtxs);
1162 if (error != TransactionError::OK) {
1163 throw JSONRPCTransactionError(error);
1164 }
1165
1167 ssTx << merged_psbt;
1168 return EncodeBase64(ssTx);
1169 },
1170 };
1171}
1172
1174 return RPCHelpMan{
1175 "finalizepsbt",
1176 "Finalize the inputs of a PSBT. If the transaction is fully signed, it "
1177 "will produce a\n"
1178 "network serialized transaction which can be broadcast with "
1179 "sendrawtransaction. Otherwise a PSBT will be\n"
1180 "created which has the final_scriptSigfields filled for inputs that "
1181 "are complete.\n"
1182 "Implements the Finalizer and Extractor roles.\n",
1183 {
1185 "A base64 string of a PSBT"},
1186 {"extract", RPCArg::Type::BOOL, RPCArg::Default{true},
1187 "If true and the transaction is complete,\n"
1188 " extract and return the complete "
1189 "transaction in normal network serialization instead of the "
1190 "PSBT."},
1191 },
1193 "",
1194 "",
1195 {
1196 {RPCResult::Type::STR, "psbt",
1197 "The base64-encoded partially signed transaction if not "
1198 "extracted"},
1200 "The hex-encoded network transaction if extracted"},
1201 {RPCResult::Type::BOOL, "complete",
1202 "If the transaction has a complete set of signatures"},
1203 }},
1204 RPCExamples{HelpExampleCli("finalizepsbt", "\"psbt\"")},
1205 [&](const RPCHelpMan &self, const Config &config,
1206 const JSONRPCRequest &request) -> UniValue {
1207 // Unserialize the transactions
1209 std::string error;
1210 if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
1212 strprintf("TX decode failed %s", error));
1213 }
1214
1215 bool extract =
1216 request.params[1].isNull() ||
1217 (!request.params[1].isNull() && request.params[1].get_bool());
1218
1220 bool complete = FinalizeAndExtractPSBT(psbtx, mtx);
1221
1222 UniValue result(UniValue::VOBJ);
1224 std::string result_str;
1225
1226 if (complete && extract) {
1227 ssTx << mtx;
1228 result_str = HexStr(ssTx);
1229 result.pushKV("hex", result_str);
1230 } else {
1231 ssTx << psbtx;
1232 result_str = EncodeBase64(ssTx.str());
1233 result.pushKV("psbt", result_str);
1234 }
1235 result.pushKV("complete", complete);
1236
1237 return result;
1238 },
1239 };
1240}
1241
1243 return RPCHelpMan{
1244 "createpsbt",
1245 "Creates a transaction in the Partially Signed Transaction format.\n"
1246 "Implements the Creator role.\n",
1247 {
1248 {
1249 "inputs",
1252 "The json objects",
1253 {
1254 {
1255 "",
1258 "",
1259 {
1260 {"txid", RPCArg::Type::STR_HEX,
1261 RPCArg::Optional::NO, "The transaction id"},
1263 "The output number"},
1264 {"sequence", RPCArg::Type::NUM,
1265 RPCArg::DefaultHint{"depends on the value of the "
1266 "'locktime' argument"},
1267 "The sequence number"},
1268 },
1269 },
1270 },
1271 },
1272 {"outputs",
1275 "The outputs (key-value pairs), where none of "
1276 "the keys are duplicated.\n"
1277 "That is, each address can only appear once and there can only "
1278 "be one 'data' object.\n"
1279 "For compatibility reasons, a dictionary, which holds the "
1280 "key-value pairs directly, is also\n"
1281 " accepted as second parameter.",
1282 {
1283 {
1284 "",
1287 "",
1288 {
1290 "A key-value pair. The key (string) is the "
1291 "bitcoin address, the value (float or string) is "
1292 "the amount in " +
1294 },
1295 },
1296 {
1297 "",
1300 "",
1301 {
1303 "A key-value pair. The key must be \"data\", the "
1304 "value is hex-encoded data"},
1305 },
1306 },
1307 },
1309 {"locktime", RPCArg::Type::NUM, RPCArg::Default{0},
1310 "Raw locktime. Non-0 value also locktime-activates inputs"},
1311 },
1313 "The resulting raw transaction (base64-encoded string)"},
1315 "createpsbt", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
1316 "\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"")},
1317 [&](const RPCHelpMan &self, const Config &config,
1318 const JSONRPCRequest &request) -> UniValue {
1319 CMutableTransaction rawTx =
1320 ConstructTransaction(config.GetChainParams(), request.params[0],
1321 request.params[1], request.params[2]);
1322
1323 // Make a blank psbt
1325 psbtx.tx = rawTx;
1326 for (size_t i = 0; i < rawTx.vin.size(); ++i) {
1327 psbtx.inputs.push_back(PSBTInput());
1328 }
1329 for (size_t i = 0; i < rawTx.vout.size(); ++i) {
1330 psbtx.outputs.push_back(PSBTOutput());
1331 }
1332
1333 // Serialize the PSBT
1335 ssTx << psbtx;
1336
1337 return EncodeBase64(ssTx);
1338 },
1339 };
1340}
1341
1343 return RPCHelpMan{
1344 "converttopsbt",
1345 "Converts a network serialized transaction to a PSBT. "
1346 "This should be used only with createrawtransaction and "
1347 "fundrawtransaction\n"
1348 "createpsbt and walletcreatefundedpsbt should be used for new "
1349 "applications.\n",
1350 {
1352 "The hex string of a raw transaction"},
1353 {"permitsigdata", RPCArg::Type::BOOL, RPCArg::Default{false},
1354 "If true, any signatures in the input will be discarded and "
1355 "conversion.\n"
1356 " will continue. If false, RPC will "
1357 "fail if any signatures are present."},
1358 },
1360 "The resulting raw transaction (base64-encoded string)"},
1362 "\nCreate a transaction\n" +
1363 HelpExampleCli("createrawtransaction",
1364 "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
1365 "\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") +
1366 "\nConvert the transaction to a PSBT\n" +
1367 HelpExampleCli("converttopsbt", "\"rawtransaction\"")},
1368 [&](const RPCHelpMan &self, const Config &config,
1369 const JSONRPCRequest &request) -> UniValue {
1370 // parse hex string from parameter
1372 bool permitsigdata = request.params[1].isNull()
1373 ? false
1374 : request.params[1].get_bool();
1375 if (!DecodeHexTx(tx, request.params[0].get_str())) {
1377 "TX decode failed");
1378 }
1379
1380 // Remove all scriptSigs from inputs
1381 for (CTxIn &input : tx.vin) {
1382 if (!input.scriptSig.empty() && !permitsigdata) {
1384 "Inputs must not have scriptSigs");
1385 }
1386 input.scriptSig.clear();
1387 }
1388
1389 // Make a blank psbt
1391 psbtx.tx = tx;
1392 for (size_t i = 0; i < tx.vin.size(); ++i) {
1393 psbtx.inputs.push_back(PSBTInput());
1394 }
1395 for (size_t i = 0; i < tx.vout.size(); ++i) {
1396 psbtx.outputs.push_back(PSBTOutput());
1397 }
1398
1399 // Serialize the PSBT
1401 ssTx << psbtx;
1402
1403 return EncodeBase64(ssTx);
1404 },
1405 };
1406}
1407
1409 return RPCHelpMan{
1410 "utxoupdatepsbt",
1411 "Updates all inputs and outputs in a PSBT with data from output "
1412 "descriptors, the UTXO set or the mempool.\n",
1413 {
1415 "A base64 string of a PSBT"},
1416 {"descriptors",
1419 "An array of either strings or objects",
1420 {
1422 "An output descriptor"},
1423 {"",
1426 "An object with an output descriptor and extra information",
1427 {
1429 "An output descriptor"},
1430 {"range", RPCArg::Type::RANGE, RPCArg::Default{1000},
1431 "Up to what index HD chains should be explored (either "
1432 "end or [begin,end])"},
1433 }},
1434 }},
1435 },
1437 "The base64-encoded partially signed transaction with inputs "
1438 "updated"},
1439 RPCExamples{HelpExampleCli("utxoupdatepsbt", "\"psbt\"")},
1440 [&](const RPCHelpMan &self, const Config &config,
1441 const JSONRPCRequest &request) -> UniValue {
1442 // Unserialize the transactions
1444 std::string error;
1445 if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
1447 strprintf("TX decode failed %s", error));
1448 }
1449
1450 // Parse descriptors, if any.
1451 FlatSigningProvider provider;
1452 if (!request.params[1].isNull()) {
1453 auto descs = request.params[1].get_array();
1454 for (size_t i = 0; i < descs.size(); ++i) {
1455 EvalDescriptorStringOrObject(descs[i], provider);
1456 }
1457 }
1458 // We don't actually need private keys further on; hide them as a
1459 // precaution.
1460 HidingSigningProvider public_provider(&provider, /* nosign */ true,
1461 /* nobip32derivs */ false);
1462
1463 // Fetch previous transactions (inputs):
1464 CCoinsView viewDummy;
1465 CCoinsViewCache view(&viewDummy);
1466 {
1467 NodeContext &node = EnsureAnyNodeContext(request.context);
1468 const CTxMemPool &mempool = EnsureMemPool(node);
1470 LOCK2(cs_main, mempool.cs);
1471 CCoinsViewCache &viewChain =
1472 chainman.ActiveChainstate().CoinsTip();
1473 CCoinsViewMemPool viewMempool(&viewChain, mempool);
1474 // temporarily switch cache backend to db+mempool view
1475 view.SetBackend(viewMempool);
1476
1477 for (const CTxIn &txin : psbtx.tx->vin) {
1478 // Load entries from viewChain into view; can fail.
1479 view.AccessCoin(txin.prevout);
1480 }
1481
1482 // switch back to avoid locking mempool for too long
1483 view.SetBackend(viewDummy);
1484 }
1485
1486 // Fill the inputs
1487 for (size_t i = 0; i < psbtx.tx->vin.size(); ++i) {
1488 PSBTInput &input = psbtx.inputs.at(i);
1489
1490 if (!input.utxo.IsNull()) {
1491 continue;
1492 }
1493
1494 // Update script/keypath information using descriptor data.
1495 // Note that SignPSBTInput does a lot more than just
1496 // constructing ECDSA signatures we don't actually care about
1497 // those here, in fact.
1498 SignPSBTInput(public_provider, psbtx, i,
1499 /* sighash_type */ SigHashType().withForkId());
1500 }
1501
1502 // Update script/keypath information using descriptor data.
1503 for (unsigned int i = 0; i < psbtx.tx->vout.size(); ++i) {
1504 UpdatePSBTOutput(public_provider, psbtx, i);
1505 }
1506
1508 ssTx << psbtx;
1509 return EncodeBase64(ssTx);
1510 },
1511 };
1512}
1513
1515 return RPCHelpMan{
1516 "joinpsbts",
1517 "Joins multiple distinct PSBTs with different inputs and outputs "
1518 "into one PSBT with inputs and outputs from all of the PSBTs\n"
1519 "No input in any of the PSBTs can be in more than one of the PSBTs.\n",
1520 {{"txs",
1523 "The base64 strings of partially signed transactions",
1525 "A base64 string of a PSBT"}}}},
1527 "The base64-encoded partially signed transaction"},
1528 RPCExamples{HelpExampleCli("joinpsbts", "\"psbt\"")},
1529 [&](const RPCHelpMan &self, const Config &config,
1530 const JSONRPCRequest &request) -> UniValue {
1531 // Unserialize the transactions
1532 std::vector<PartiallySignedTransaction> psbtxs;
1533 UniValue txs = request.params[0].get_array();
1534
1535 if (txs.size() <= 1) {
1536 throw JSONRPCError(
1538 "At least two PSBTs are required to join PSBTs.");
1539 }
1540
1541 uint32_t best_version = 1;
1542 uint32_t best_locktime = 0xffffffff;
1543 for (size_t i = 0; i < txs.size(); ++i) {
1545 std::string error;
1546 if (!DecodeBase64PSBT(psbtx, txs[i].get_str(), error)) {
1548 strprintf("TX decode failed %s", error));
1549 }
1550 psbtxs.push_back(psbtx);
1551 // Choose the highest version number
1552 if (static_cast<uint32_t>(psbtx.tx->nVersion) > best_version) {
1553 best_version = static_cast<uint32_t>(psbtx.tx->nVersion);
1554 }
1555 // Choose the lowest lock time
1556 if (psbtx.tx->nLockTime < best_locktime) {
1557 best_locktime = psbtx.tx->nLockTime;
1558 }
1559 }
1560
1561 // Create a blank psbt where everything will be added
1562 PartiallySignedTransaction merged_psbt;
1563 merged_psbt.tx = CMutableTransaction();
1564 merged_psbt.tx->nVersion = static_cast<int32_t>(best_version);
1565 merged_psbt.tx->nLockTime = best_locktime;
1566
1567 // Merge
1568 for (auto &psbt : psbtxs) {
1569 for (size_t i = 0; i < psbt.tx->vin.size(); ++i) {
1570 if (!merged_psbt.AddInput(psbt.tx->vin[i],
1571 psbt.inputs[i])) {
1572 throw JSONRPCError(
1574 strprintf("Input %s:%d exists in multiple PSBTs",
1575 psbt.tx->vin[i]
1576 .prevout.GetTxId()
1577 .ToString()
1578 .c_str(),
1579 psbt.tx->vin[i].prevout.GetN()));
1580 }
1581 }
1582 for (size_t i = 0; i < psbt.tx->vout.size(); ++i) {
1583 merged_psbt.AddOutput(psbt.tx->vout[i], psbt.outputs[i]);
1584 }
1585 merged_psbt.unknown.insert(psbt.unknown.begin(),
1586 psbt.unknown.end());
1587 }
1588
1589 // Generate list of shuffled indices for shuffling inputs and
1590 // outputs of the merged PSBT
1591 std::vector<int> input_indices(merged_psbt.inputs.size());
1592 std::iota(input_indices.begin(), input_indices.end(), 0);
1593 std::vector<int> output_indices(merged_psbt.outputs.size());
1594 std::iota(output_indices.begin(), output_indices.end(), 0);
1595
1596 // Shuffle input and output indices lists
1597 Shuffle(input_indices.begin(), input_indices.end(),
1599 Shuffle(output_indices.begin(), output_indices.end(),
1601
1602 PartiallySignedTransaction shuffled_psbt;
1603 shuffled_psbt.tx = CMutableTransaction();
1604 shuffled_psbt.tx->nVersion = merged_psbt.tx->nVersion;
1605 shuffled_psbt.tx->nLockTime = merged_psbt.tx->nLockTime;
1606 for (int i : input_indices) {
1607 shuffled_psbt.AddInput(merged_psbt.tx->vin[i],
1608 merged_psbt.inputs[i]);
1609 }
1610 for (int i : output_indices) {
1611 shuffled_psbt.AddOutput(merged_psbt.tx->vout[i],
1612 merged_psbt.outputs[i]);
1613 }
1614 shuffled_psbt.unknown.insert(merged_psbt.unknown.begin(),
1615 merged_psbt.unknown.end());
1616
1618 ssTx << shuffled_psbt;
1619 return EncodeBase64(ssTx);
1620 },
1621 };
1622}
1623
1625 return RPCHelpMan{
1626 "analyzepsbt",
1627 "Analyzes and provides information about the current status of a "
1628 "PSBT and its inputs\n",
1630 "A base64 string of a PSBT"}},
1631 RPCResult{
1633 "",
1634 "",
1635 {
1637 "inputs",
1638 "",
1639 {
1641 "",
1642 "",
1643 {
1644 {RPCResult::Type::BOOL, "has_utxo",
1645 "Whether a UTXO is provided"},
1646 {RPCResult::Type::BOOL, "is_final",
1647 "Whether the input is finalized"},
1649 "missing",
1650 /* optional */ true,
1651 "Things that are missing that are required to "
1652 "complete this input",
1653 {
1655 "pubkeys",
1656 /* optional */ true,
1657 "",
1658 {
1659 {RPCResult::Type::STR_HEX, "keyid",
1660 "Public key ID, hash160 of the public "
1661 "key, of a public key whose BIP 32 "
1662 "derivation path is missing"},
1663 }},
1665 "signatures",
1666 /* optional */ true,
1667 "",
1668 {
1669 {RPCResult::Type::STR_HEX, "keyid",
1670 "Public key ID, hash160 of the public "
1671 "key, of a public key whose signature is "
1672 "missing"},
1673 }},
1674 {RPCResult::Type::STR_HEX, "redeemscript",
1675 /* optional */ true,
1676 "Hash160 of the redeemScript that is missing"},
1677 }},
1678 {RPCResult::Type::STR, "next", /* optional */ true,
1679 "Role of the next person that this input needs to "
1680 "go to"},
1681 }},
1682 }},
1683 {RPCResult::Type::NUM, "estimated_vsize", /* optional */ true,
1684 "Estimated vsize of the final signed transaction"},
1685 {RPCResult::Type::STR_AMOUNT, "estimated_feerate",
1686 /* optional */ true,
1687 "Estimated feerate of the final signed transaction in " +
1689 "/kB. Shown only if all UTXO slots in the PSBT have been "
1690 "filled"},
1691 {RPCResult::Type::STR_AMOUNT, "fee", /* optional */ true,
1692 "The transaction fee paid. Shown only if all UTXO slots in "
1693 "the PSBT have been filled"},
1694 {RPCResult::Type::STR, "next",
1695 "Role of the next person that this psbt needs to go to"},
1696 {RPCResult::Type::STR, "error", /* optional */ true,
1697 "Error message (if there is one)"},
1698 }},
1699 RPCExamples{HelpExampleCli("analyzepsbt", "\"psbt\"")},
1700 [&](const RPCHelpMan &self, const Config &config,
1701 const JSONRPCRequest &request) -> UniValue {
1702 // Unserialize the transaction
1704 std::string error;
1705 if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
1707 strprintf("TX decode failed %s", error));
1708 }
1709
1710 PSBTAnalysis psbta = AnalyzePSBT(psbtx);
1711
1712 UniValue result(UniValue::VOBJ);
1713 UniValue inputs_result(UniValue::VARR);
1714 for (const auto &input : psbta.inputs) {
1715 UniValue input_univ(UniValue::VOBJ);
1716 UniValue missing(UniValue::VOBJ);
1717
1718 input_univ.pushKV("has_utxo", input.has_utxo);
1719 input_univ.pushKV("is_final", input.is_final);
1720 input_univ.pushKV("next", PSBTRoleName(input.next));
1721
1722 if (!input.missing_pubkeys.empty()) {
1723 UniValue missing_pubkeys_univ(UniValue::VARR);
1724 for (const CKeyID &pubkey : input.missing_pubkeys) {
1725 missing_pubkeys_univ.push_back(HexStr(pubkey));
1726 }
1727 missing.pushKV("pubkeys", missing_pubkeys_univ);
1728 }
1729 if (!input.missing_redeem_script.IsNull()) {
1730 missing.pushKV("redeemscript",
1731 HexStr(input.missing_redeem_script));
1732 }
1733 if (!input.missing_sigs.empty()) {
1734 UniValue missing_sigs_univ(UniValue::VARR);
1735 for (const CKeyID &pubkey : input.missing_sigs) {
1736 missing_sigs_univ.push_back(HexStr(pubkey));
1737 }
1738 missing.pushKV("signatures", missing_sigs_univ);
1739 }
1740 if (!missing.getKeys().empty()) {
1741 input_univ.pushKV("missing", missing);
1742 }
1743 inputs_result.push_back(input_univ);
1744 }
1745 if (!inputs_result.empty()) {
1746 result.pushKV("inputs", inputs_result);
1747 }
1748 if (psbta.estimated_vsize != std::nullopt) {
1749 result.pushKV("estimated_vsize", (int)*psbta.estimated_vsize);
1750 }
1751 if (psbta.estimated_feerate != std::nullopt) {
1752 result.pushKV("estimated_feerate",
1753 psbta.estimated_feerate->GetFeePerK());
1754 }
1755 if (psbta.fee != std::nullopt) {
1756 result.pushKV("fee", *psbta.fee);
1757 }
1758 result.pushKV("next", PSBTRoleName(psbta.next));
1759 if (!psbta.error.empty()) {
1760 result.pushKV("error", psbta.error);
1761 }
1762
1763 return result;
1764 },
1765 };
1766}
1767
1769 return RPCHelpMan{
1770 "gettransactionstatus",
1771 "Return the current pool a transaction belongs to\n",
1772 {
1774 "The transaction id"},
1775 },
1776 RPCResult{
1778 "",
1779 "",
1780 {
1781 {RPCResult::Type::STR, "pool",
1782 "In which pool the transaction is currently located, "
1783 "either none, mempool, orphanage or conflicting"},
1784 {RPCResult::Type::STR, "block",
1785 "If the transaction is mined, this is the blockhash of the "
1786 "mining block, otherwise \"none\". This field is only "
1787 "present if -txindex is enabled."},
1788 }},
1789 RPCExamples{HelpExampleCli("gettransactionstatus", "\"txid\"")},
1790 [&](const RPCHelpMan &self, const Config &config,
1791 const JSONRPCRequest &request) -> UniValue {
1792 const NodeContext &node = EnsureAnyNodeContext(request.context);
1793 CTxMemPool &mempool = EnsureMemPool(node);
1794
1795 TxId txid = TxId(ParseHashV(request.params[0], "parameter 1"));
1796
1798
1799 if (mempool.exists(txid)) {
1800 ret.pushKV("pool", "mempool");
1801 } else if (mempool.withOrphanage(
1802 [&txid](const TxOrphanage &orphanage) {
1803 return orphanage.HaveTx(txid);
1804 })) {
1805 ret.pushKV("pool", "orphanage");
1806 } else if (mempool.withConflicting(
1807 [&txid](const TxConflicting &conflicting) {
1808 return conflicting.HaveTx(txid);
1809 })) {
1810 ret.pushKV("pool", "conflicting");
1811 } else {
1812 ret.pushKV("pool", "none");
1813 }
1814
1815 if (g_txindex) {
1816 if (!g_txindex->BlockUntilSyncedToCurrentChain()) {
1817 throw JSONRPCError(
1819 "Blockchain transactions are still in the process of "
1820 "being indexed");
1821 }
1822
1823 CTransactionRef tx;
1824 BlockHash blockhash;
1825 if (g_txindex->FindTx(txid, blockhash, tx)) {
1826 ret.pushKV("block", blockhash.GetHex());
1827 } else {
1828 ret.pushKV("block", "none");
1829 }
1830 }
1831
1832 return ret;
1833 },
1834 };
1835}
1836
1838 // clang-format off
1839 static const CRPCCommand commands[] = {
1840 // category actor (function)
1841 // ------------------ ----------------------
1842 { "rawtransactions", getrawtransaction, },
1843 { "rawtransactions", createrawtransaction, },
1844 { "rawtransactions", decoderawtransaction, },
1845 { "rawtransactions", decodescript, },
1846 { "rawtransactions", combinerawtransaction, },
1847 { "rawtransactions", signrawtransactionwithkey, },
1848 { "rawtransactions", decodepsbt, },
1849 { "rawtransactions", combinepsbt, },
1850 { "rawtransactions", finalizepsbt, },
1851 { "rawtransactions", createpsbt, },
1852 { "rawtransactions", converttopsbt, },
1853 { "rawtransactions", utxoupdatepsbt, },
1854 { "rawtransactions", joinpsbts, },
1855 { "rawtransactions", analyzepsbt, },
1856 { "rawtransactions", gettransactionstatus, },
1857 };
1858 // clang-format on
1859 for (const auto &c : commands) {
1860 t.appendCommand(c.name, &c);
1861 }
1862}
bool MoneyRange(const Amount nValue)
Definition: amount.h:166
std::string WriteHDKeypath(const std::vector< uint32_t > &keypath)
Write HD keypaths as strings.
Definition: bip32.cpp:66
uint256 hashMerkleRoot
Definition: block.h:28
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: blockindex.h:25
int64_t GetBlockTime() const
Definition: blockindex.h:160
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: blockindex.h:38
int Height() const
Return the maximal height in the chain.
Definition: chain.h:186
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
Definition: chain.h:166
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
Definition: chainparams.h:86
const CBlock & GenesisBlock() const
Definition: chainparams.h:112
void SetBackend(CCoinsView &viewIn)
Definition: coins.cpp:47
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:363
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
Definition: coins.cpp:196
Abstract view on the open txout dataset.
Definition: coins.h:305
CCoinsView that brings transactions from a mempool into view.
Definition: txmempool.h:647
An encapsulated secp256k1 private key.
Definition: key.h:28
bool IsValid() const
Check whether this private key is valid.
Definition: key.h:97
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:22
A mutable version of CTransaction.
Definition: transaction.h:274
std::vector< CTxOut > vout
Definition: transaction.h:277
std::vector< CTxIn > vin
Definition: transaction.h:276
RPC command dispatcher.
Definition: server.h:194
void appendCommand(const std::string &name, const CRPCCommand *pcmd)
Appends a CRPCCommand to the dispatch table.
Definition: server.cpp:328
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition: txmempool.h:221
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
Definition: txmempool.h:317
bool exists(const TxId &txid) const
Definition: txmempool.h:530
auto withOrphanage(Callable &&func) const EXCLUSIVE_LOCKS_REQUIRED(!cs_orphanage)
Definition: txmempool.h:590
auto withConflicting(Callable &&func) const EXCLUSIVE_LOCKS_REQUIRED(!cs_conflicting)
Definition: txmempool.h:598
An output of a transaction.
Definition: transaction.h:128
CScript scriptPubKey
Definition: transaction.h:131
Amount nValue
Definition: transaction.h:130
bool IsNull() const
Definition: transaction.h:145
Chainstate stores and provides an API to update our local knowledge of the current best chain.
Definition: validation.h:734
CChain m_chain
The current chain of blockheaders we consult and build on.
Definition: validation.h:833
node::BlockManager & m_blockman
Reference to a BlockManager instance which itself is shared across all Chainstate instances.
Definition: validation.h:791
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
Definition: validation.h:1186
SnapshotCompletionResult MaybeCompleteSnapshotValidation() EXCLUSIVE_LOCKS_REQUIRED(const CBlockIndex *GetSnapshotBaseBlock() const EXCLUSIVE_LOCKS_REQUIRED(Chainstate ActiveChainstate)() const
Once the background validation chainstate has reached the height which is the base of the UTXO snapsh...
Definition: validation.h:1437
CChain & ActiveChain() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
Definition: validation.h:1438
node::BlockManager m_blockman
A single BlockManager instance is shared across each constructed chainstate to avoid duplicating bloc...
Definition: validation.h:1327
A UTXO entry.
Definition: coins.h:29
CTxOut & GetTxOut()
Definition: coins.h:50
bool IsSpent() const
Definition: coins.h:48
Definition: config.h:19
std::string str() const
Definition: streams.h:195
Fast randomness source.
Definition: random.h:156
Fillable signing provider that keeps keys in an address->secret map.
virtual bool AddKey(const CKey &key)
A signature creator for transactions.
Definition: sign.h:38
Signature hash type wrapper class.
Definition: sighashtype.h:37
uint32_t getRawSigHashType() const
Definition: sighashtype.h:83
void push_back(UniValue val)
Definition: univalue.cpp:96
const std::string & get_str() const
const UniValue & find_value(std::string_view key) const
Definition: univalue.cpp:229
@ VOBJ
Definition: univalue.h:31
@ VARR
Definition: univalue.h:32
size_t size() const
Definition: univalue.h:92
const std::vector< std::string > & getKeys() const
bool empty() const
Definition: univalue.h:90
bool isStr() const
Definition: univalue.h:108
const UniValue & get_array() const
void pushKV(std::string key, UniValue val)
Definition: univalue.cpp:115
bool IsNull() const
Definition: uint256.h:32
std::string GetHex() const
Definition: uint256.cpp:16
CBlockIndex * LookupBlockIndex(const BlockHash &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
void ScriptToUniv(const CScript &script, UniValue &out, bool include_address)
Definition: core_write.cpp:179
void TxToUniv(const CTransaction &tx, const BlockHash &hashBlock, UniValue &entry, bool include_hex=true, const CTxUndo *txundo=nullptr)
Definition: core_write.cpp:221
std::string EncodeHexTx(const CTransaction &tx)
Definition: core_write.cpp:173
std::string SighashToStr(uint8_t sighash_type)
Definition: core_write.cpp:89
void ScriptPubKeyToUniv(const CScript &scriptPubKey, UniValue &out, bool fIncludeHex)
Definition: core_write.cpp:194
bool DecodeHexTx(CMutableTransaction &tx, const std::string &strHexTx)
Definition: core_read.cpp:199
std::string ScriptToAsmStr(const CScript &script, const bool fAttemptSighashDecode=false)
Create the assembly string representation of a CScript object.
Definition: core_write.cpp:106
static uint32_t ReadBE32(const uint8_t *ptr)
Definition: common.h:56
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition: cs_main.cpp:7
TransactionError
Definition: error.h:22
std::string EncodeDestination(const CTxDestination &dest, const Config &config)
Definition: key_io.cpp:167
CKey DecodeSecret(const std::string &str)
Definition: key_io.cpp:77
Definition: init.h:31
PSBTAnalysis AnalyzePSBT(PartiallySignedTransaction psbtx)
Provides helpful miscellaneous information about where a PSBT is in the signing workflow.
Definition: psbt.cpp:16
CTransactionRef GetTransaction(const CBlockIndex *const block_index, const CTxMemPool *const mempool, const TxId &txid, BlockHash &hashBlock, const BlockManager &blockman)
Return transaction with a given txid.
void FindCoins(const NodeContext &node, std::map< COutPoint, Coin > &coins)
Look up unspent output information.
Definition: coin.cpp:12
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:315
SchnorrSig sig
Definition: processor.cpp:523
bool DecodeBase64PSBT(PartiallySignedTransaction &psbt, const std::string &base64_tx, std::string &error)
Decode a base64ed PSBT into a PartiallySignedTransaction.
Definition: psbt.cpp:296
void UpdatePSBTOutput(const SigningProvider &provider, PartiallySignedTransaction &psbt, int index)
Updates a PSBTOutput with information from provider.
Definition: psbt.cpp:164
std::string PSBTRoleName(const PSBTRole role)
Definition: psbt.cpp:279
bool FinalizeAndExtractPSBT(PartiallySignedTransaction &psbtx, CMutableTransaction &result)
Finalizes a PSBT if possible, and extracts it to a CMutableTransaction if it could be finalized.
Definition: psbt.cpp:247
TransactionError CombinePSBTs(PartiallySignedTransaction &out, const std::vector< PartiallySignedTransaction > &psbtxs)
Combines PSBTs with the same underlying transaction, resulting in a single PSBT with all partial sign...
Definition: psbt.cpp:264
bool SignPSBTInput(const SigningProvider &provider, PartiallySignedTransaction &psbt, int index, SigHashType sighash, SignatureData *out_sigdata, bool use_dummy)
Signs a PSBTInput, verifying that all provided data matches what is being signed.
Definition: psbt.cpp:186
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
Definition: random.h:297
RPCHelpMan joinpsbts()
static RPCHelpMan getrawtransaction()
static RPCHelpMan converttopsbt()
RPCHelpMan analyzepsbt()
static RPCHelpMan decoderawtransaction()
static RPCHelpMan combinepsbt()
static RPCHelpMan decodepsbt()
RPCHelpMan gettransactionstatus()
static RPCHelpMan decodescript()
static RPCHelpMan createpsbt()
RPCHelpMan utxoupdatepsbt()
static RPCHelpMan combinerawtransaction()
static void TxToJSON(const CTransaction &tx, const BlockHash &hashBlock, UniValue &entry, Chainstate &active_chainstate)
static RPCHelpMan signrawtransactionwithkey()
static RPCHelpMan createrawtransaction()
static RPCHelpMan finalizepsbt()
void RegisterRawTransactionRPCCommands(CRPCTable &t)
void SignTransaction(CMutableTransaction &mtx, const SigningProvider *keystore, const std::map< COutPoint, Coin > &coins, const UniValue &hashType, UniValue &result)
Sign a transaction with the given keystore and previous transactions.
CMutableTransaction ConstructTransaction(const CChainParams &params, const UniValue &inputs_in, const UniValue &outputs_in, const UniValue &locktime)
Create a transaction from univalue parameters.
void ParsePrevouts(const UniValue &prevTxsUnival, FillableSigningProvider *keystore, std::map< COutPoint, Coin > &coins)
Parse a prevtxs UniValue array and get the map of coins from it.
UniValue JSONRPCError(int code, const std::string &message)
Definition: request.cpp:58
@ RPC_MISC_ERROR
General application defined errors std::exception thrown in command handling.
Definition: protocol.h:38
@ RPC_INVALID_PARAMETER
Invalid, missing or duplicate parameter.
Definition: protocol.h:46
@ RPC_VERIFY_ERROR
General error during transaction or block submission.
Definition: protocol.h:52
@ RPC_DESERIALIZATION_ERROR
Error parsing or validating structure in raw format.
Definition: protocol.h:50
@ RPC_INVALID_ADDRESS_OR_KEY
Invalid address or key.
Definition: protocol.h:42
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: util.cpp:153
UniValue JSONRPCTransactionError(TransactionError terr, const std::string &err_string)
Definition: util.cpp:336
std::vector< uint8_t > ParseHexV(const UniValue &v, std::string strName)
Definition: util.cpp:97
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:170
std::vector< CScript > EvalDescriptorStringOrObject(const UniValue &scanobject, FlatSigningProvider &provider)
Evaluate a descriptor given as a string, or as a {"desc":...,"range":...} object, with default range ...
Definition: util.cpp:1362
const std::string UNIX_EPOCH_TIME
String used to describe UNIX epoch time in documentation, factored out to a constant for consistency.
Definition: util.cpp:25
std::string GetAllOutputTypes()
Definition: util.cpp:308
uint256 ParseHashV(const UniValue &v, std::string strName)
Utilities: convert hex-encoded values (throws error if not hex).
Definition: util.cpp:76
#define extract(n)
Extract the lowest 64 bits of (c0,c1,c2) into n, and left shift the number 64 bits.
@ SER_NETWORK
Definition: serialize.h:154
NodeContext & EnsureAnyNodeContext(const std::any &context)
Definition: server_util.cpp:21
CTxMemPool & EnsureMemPool(const NodeContext &node)
Definition: server_util.cpp:29
ChainstateManager & EnsureChainman(const NodeContext &node)
Definition: server_util.cpp:52
bool ProduceSignature(const SigningProvider &provider, const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
Definition: sign.cpp:198
void UpdateInput(CTxIn &input, const SignatureData &data)
Definition: sign.cpp:331
SignatureData DataFromTransaction(const CMutableTransaction &tx, unsigned int nIn, const CTxOut &txout)
Extract signature data from a transaction input, and insert it.
Definition: sign.cpp:275
const SigningProvider & DUMMY_SIGNING_PROVIDER
Definition: amount.h:19
static constexpr Amount zero() noexcept
Definition: amount.h:32
A BlockHash is a unqiue identifier for a block.
Definition: blockhash.h:13
static const Currency & get()
Definition: amount.cpp:18
std::string ticker
Definition: amount.h:150
A structure for PSBTs which contain per-input information.
Definition: psbt.h:44
std::map< CPubKey, KeyOriginInfo > hd_keypaths
Definition: psbt.h:48
std::map< CKeyID, SigPair > partial_sigs
Definition: psbt.h:49
SigHashType sighash_type
Definition: psbt.h:51
std::map< std::vector< uint8_t >, std::vector< uint8_t > > unknown
Definition: psbt.h:50
CScript redeem_script
Definition: psbt.h:46
CScript final_script_sig
Definition: psbt.h:47
CTxOut utxo
Definition: psbt.h:45
A structure for PSBTs which contains per output information.
Definition: psbt.h:233
CScript redeem_script
Definition: psbt.h:234
std::map< CPubKey, KeyOriginInfo > hd_keypaths
Definition: psbt.h:235
std::map< std::vector< uint8_t >, std::vector< uint8_t > > unknown
Definition: psbt.h:236
A version of CTransaction with the PSBT format.
Definition: psbt.h:334
std::map< std::vector< uint8_t >, std::vector< uint8_t > > unknown
Definition: psbt.h:338
bool AddOutput(const CTxOut &txout, const PSBTOutput &psbtout)
Definition: psbt.cpp:50
std::vector< PSBTInput > inputs
Definition: psbt.h:336
std::optional< CMutableTransaction > tx
Definition: psbt.h:335
bool AddInput(const CTxIn &txin, PSBTInput &psbtin)
Definition: psbt.cpp:38
std::vector< PSBTOutput > outputs
Definition: psbt.h:337
@ RANGE
Special type that is a NUM or [NUM,NUM].
@ OBJ_USER_KEYS
Special type where the user must set the keys e.g.
@ STR_HEX
Special type that is a STR with only hex chars.
@ AMOUNT
Special type representing a floating point amount (can be either NUM or STR)
std::string DefaultHint
Hint for default value.
Definition: util.h:206
@ OMITTED
Optional argument for which the default value is omitted from help text for one of two reasons:
@ NO
Required arg.
bool skip_type_check
Definition: util.h:140
@ ELISION
Special type to denote elision (...)
@ NUM_TIME
Special numeric to denote unix epoch time.
@ OBJ_DYN
Special dictionary with keys that are not literals.
@ STR_HEX
Special string with only hex chars.
@ STR_AMOUNT
Special string to represent a floating point amount.
void MergeSignatureData(SignatureData sigdata)
Definition: sign.cpp:335
A TxId is the identifier of a transaction.
Definition: txid.h:14
NodeContext struct containing references to chain state and connection state.
Definition: context.h:48
Holds the results of AnalyzePSBT (miscellaneous information about a PSBT)
Definition: psbt.h:35
std::vector< PSBTInputAnalysis > inputs
More information about the individual inputs of the transaction.
Definition: psbt.h:43
std::string error
Error message.
Definition: psbt.h:47
std::optional< Amount > fee
Amount of fee being paid by the transaction.
Definition: psbt.h:41
std::optional< size_t > estimated_vsize
Estimated weight of the transaction.
Definition: psbt.h:37
std::optional< CFeeRate > estimated_feerate
Estimated feerate (fee / weight) of the transaction.
Definition: psbt.h:39
PSBTRole next
Which of the BIP 174 roles needs to handle the transaction next.
Definition: psbt.h:45
#define LOCK2(cs1, cs2)
Definition: sync.h:309
#define LOCK(cs)
Definition: sync.h:306
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:357
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1202
std::unique_ptr< TxIndex > g_txindex
The global transaction index, used in GetTransaction. May be null.
Definition: txindex.cpp:16
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
std::string EncodeBase64(Span< const uint8_t > input)
static const int PROTOCOL_VERSION
network protocol versioning
Definition: version.h:11