Bitcoin ABC 0.31.2
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
51using node::FindCoins;
55
56static void TxToJSON(const CTransaction &tx, const BlockHash &hashBlock,
57 UniValue &entry, Chainstate &active_chainstate) {
58 // Call into TxToUniv() in bitcoin-common to decode the transaction hex.
59 //
60 // Blockchain contextual information (confirmations and blocktime) is not
61 // available to code in bitcoin-common, so we query them here and push the
62 // data into the returned UniValue.
63 TxToUniv(tx, BlockHash(), entry, true, RPCSerializationFlags());
64
65 if (!hashBlock.IsNull()) {
67
68 entry.pushKV("blockhash", hashBlock.GetHex());
69 const CBlockIndex *pindex =
70 active_chainstate.m_blockman.LookupBlockIndex(hashBlock);
71 if (pindex) {
72 if (active_chainstate.m_chain.Contains(pindex)) {
73 entry.pushKV("confirmations",
74 1 + active_chainstate.m_chain.Height() -
75 pindex->nHeight);
76 entry.pushKV("time", pindex->GetBlockTime());
77 entry.pushKV("blocktime", pindex->GetBlockTime());
78 } else {
79 entry.pushKV("confirmations", 0);
80 }
81 }
82 }
83}
84
86 return RPCHelpMan{
87 "getrawtransaction",
88 "\nReturn the raw transaction data.\n"
89 "\nBy default, this call only returns a transaction if it is in the "
90 "mempool. If -txindex is enabled\n"
91 "and no blockhash argument is passed, it will return the transaction "
92 "if it is in the mempool or any block.\n"
93 "If a blockhash argument is passed, it will return the transaction if\n"
94 "the specified block is available and the transaction is in that "
95 "block.\n"
96 "\nIf verbose is 'true', returns an Object with information about "
97 "'txid'.\n"
98 "If verbose is 'false' or omitted, returns a string that is "
99 "serialized, hex-encoded data for 'txid'.\n",
100 {
102 "The transaction id"},
103 // Verbose is a boolean, but we accept an int for backward
104 // compatibility
105 {"verbose", RPCArg::Type::BOOL, RPCArg::Default{false},
106 "If false, return a string, otherwise return a json object",
109 "The block in which to look for the transaction"},
110 },
111 {
112 RPCResult{"if verbose is not set or set to false",
113 RPCResult::Type::STR, "data",
114 "The serialized, hex-encoded data for 'txid'"},
115 RPCResult{
116 "if verbose is set to true",
118 "",
119 "",
120 {
121 {RPCResult::Type::BOOL, "in_active_chain",
122 "Whether specified block is in the active chain or not "
123 "(only present with explicit \"blockhash\" argument)"},
125 "The serialized, hex-encoded data for 'txid'"},
127 "The transaction id (same as provided)"},
128 {RPCResult::Type::STR_HEX, "hash", "The transaction hash"},
129 {RPCResult::Type::NUM, "size",
130 "The serialized transaction size"},
131 {RPCResult::Type::NUM, "version", "The version"},
132 {RPCResult::Type::NUM_TIME, "locktime", "The lock time"},
134 "vin",
135 "",
136 {
138 "",
139 "",
140 {
142 "The transaction id"},
143 {RPCResult::Type::STR, "vout", ""},
145 "scriptSig",
146 "The script",
147 {
148 {RPCResult::Type::STR, "asm", "asm"},
149 {RPCResult::Type::STR_HEX, "hex", "hex"},
150 }},
151 {RPCResult::Type::NUM, "sequence",
152 "The script sequence number"},
153 }},
154 }},
156 "vout",
157 "",
158 {
160 "",
161 "",
162 {
163 {RPCResult::Type::NUM, "value",
164 "The value in " + Currency::get().ticker},
165 {RPCResult::Type::NUM, "n", "index"},
167 "scriptPubKey",
168 "",
169 {
170 {RPCResult::Type::STR, "asm", "the asm"},
171 {RPCResult::Type::STR, "hex", "the hex"},
172 {RPCResult::Type::NUM, "reqSigs",
173 "The required sigs"},
174 {RPCResult::Type::STR, "type",
175 "The type, eg 'pubkeyhash'"},
177 "addresses",
178 "",
179 {
180 {RPCResult::Type::STR, "address",
181 "bitcoin address"},
182 }},
183 }},
184 }},
185 }},
186 {RPCResult::Type::STR_HEX, "blockhash", "the block hash"},
187 {RPCResult::Type::NUM, "confirmations",
188 "The confirmations"},
189 {RPCResult::Type::NUM_TIME, "blocktime",
190 "The block time expressed in " + UNIX_EPOCH_TIME},
191 {RPCResult::Type::NUM, "time", "Same as \"blocktime\""},
192 }},
193 },
194 RPCExamples{HelpExampleCli("getrawtransaction", "\"mytxid\"") +
195 HelpExampleCli("getrawtransaction", "\"mytxid\" true") +
196 HelpExampleRpc("getrawtransaction", "\"mytxid\", true") +
197 HelpExampleCli("getrawtransaction",
198 "\"mytxid\" false \"myblockhash\"") +
199 HelpExampleCli("getrawtransaction",
200 "\"mytxid\" true \"myblockhash\"")},
201 [&](const RPCHelpMan &self, const Config &config,
202 const JSONRPCRequest &request) -> UniValue {
203 const NodeContext &node = EnsureAnyNodeContext(request.context);
205
206 bool in_active_chain = true;
207 TxId txid = TxId(ParseHashV(request.params[0], "parameter 1"));
208 const CBlockIndex *blockindex = nullptr;
209
210 const CChainParams &params = config.GetChainParams();
211 if (txid == params.GenesisBlock().hashMerkleRoot) {
212 // Special exception for the genesis block coinbase transaction
213 throw JSONRPCError(
215 "The genesis block coinbase is not considered an "
216 "ordinary transaction and cannot be retrieved");
217 }
218
219 // Accept either a bool (true) or a num (>=1) to indicate verbose
220 // output.
221 bool fVerbose = false;
222 if (!request.params[1].isNull()) {
223 fVerbose = request.params[1].isNum()
224 ? (request.params[1].getInt<int>() != 0)
225 : request.params[1].get_bool();
226 }
227
228 if (!request.params[2].isNull()) {
229 LOCK(cs_main);
230
231 BlockHash blockhash(
232 ParseHashV(request.params[2], "parameter 3"));
233 blockindex = chainman.m_blockman.LookupBlockIndex(blockhash);
234 if (!blockindex) {
236 "Block hash not found");
237 }
238 in_active_chain = chainman.ActiveChain().Contains(blockindex);
239 }
240
241 bool f_txindex_ready = false;
242 if (g_txindex && !blockindex) {
243 f_txindex_ready = g_txindex->BlockUntilSyncedToCurrentChain();
244 }
245
246 BlockHash hash_block;
247 const CTransactionRef tx =
248 GetTransaction(blockindex, node.mempool.get(), txid, hash_block,
249 chainman.m_blockman);
250 if (!tx) {
251 std::string errmsg;
252 if (blockindex) {
254 return !blockindex->nStatus.hasData())) {
256 "Block not available");
257 }
258 errmsg = "No such transaction found in the provided block";
259 } else if (!g_txindex) {
260 errmsg =
261 "No such mempool transaction. Use -txindex or provide "
262 "a block hash to enable blockchain transaction queries";
263 } else if (!f_txindex_ready) {
264 errmsg = "No such mempool transaction. Blockchain "
265 "transactions are still in the process of being "
266 "indexed";
267 } else {
268 errmsg = "No such mempool or blockchain transaction";
269 }
270 throw JSONRPCError(
272 errmsg + ". Use gettransaction for wallet transactions.");
273 }
274
275 if (!fVerbose) {
276 return EncodeHexTx(*tx, RPCSerializationFlags());
277 }
278
279 UniValue result(UniValue::VOBJ);
280 if (blockindex) {
281 result.pushKV("in_active_chain", in_active_chain);
282 }
283 TxToJSON(*tx, hash_block, result, chainman.ActiveChainstate());
284 return result;
285 },
286 };
287}
288
290 return RPCHelpMan{
291 "createrawtransaction",
292 "Create a transaction spending the given inputs and creating new "
293 "outputs.\n"
294 "Outputs can be addresses or data.\n"
295 "Returns hex-encoded raw transaction.\n"
296 "Note that the transaction's inputs are not signed, and\n"
297 "it is not stored in the wallet or transmitted to the network.\n",
298 {
299 {
300 "inputs",
303 "The inputs",
304 {
305 {
306 "",
309 "",
310 {
311 {"txid", RPCArg::Type::STR_HEX,
312 RPCArg::Optional::NO, "The transaction id"},
314 "The output number"},
315 {"sequence", RPCArg::Type::NUM,
316 RPCArg::DefaultHint{"depends on the value of the "
317 "'locktime' argument"},
318 "The sequence number"},
319 },
320 },
321 },
322 },
323 {"outputs",
326 "The outputs (key-value pairs), where none of "
327 "the keys are duplicated.\n"
328 "That is, each address can only appear once and there can only "
329 "be one 'data' object.\n"
330 "For compatibility reasons, a dictionary, which holds the "
331 "key-value pairs directly, is also\n"
332 " accepted as second parameter.",
333 {
334 {
335 "",
338 "",
339 {
341 "A key-value pair. The key (string) is the "
342 "bitcoin address, the value (float or string) is "
343 "the amount in " +
345 },
346 },
347 {
348 "",
351 "",
352 {
354 "A key-value pair. The key must be \"data\", the "
355 "value is hex-encoded data"},
356 },
357 },
358 },
360 {"locktime", RPCArg::Type::NUM, RPCArg::Default{0},
361 "Raw locktime. Non-0 value also locktime-activates inputs"},
362 },
363 RPCResult{RPCResult::Type::STR_HEX, "transaction",
364 "hex string of the transaction"},
366 HelpExampleCli("createrawtransaction",
367 "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
368 "\" \"[{\\\"address\\\":10000.00}]\"") +
369 HelpExampleCli("createrawtransaction",
370 "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
371 "\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") +
372 HelpExampleRpc("createrawtransaction",
373 "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
374 "\", \"[{\\\"address\\\":10000.00}]\"") +
375 HelpExampleRpc("createrawtransaction",
376 "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
377 "\", \"[{\\\"data\\\":\\\"00010203\\\"}]\"")},
378 [&](const RPCHelpMan &self, const Config &config,
379 const JSONRPCRequest &request) -> UniValue {
380 CMutableTransaction rawTx =
381 ConstructTransaction(config.GetChainParams(), request.params[0],
382 request.params[1], request.params[2]);
383
384 return EncodeHexTx(CTransaction(rawTx));
385 },
386 };
387}
388
390 return RPCHelpMan{
391 "decoderawtransaction",
392 "Return a JSON object representing the serialized, hex-encoded "
393 "transaction.\n",
394 {
396 "The transaction hex string"},
397 },
398 RPCResult{
400 "",
401 "",
402 {
403 {RPCResult::Type::STR_HEX, "txid", "The transaction id"},
404 {RPCResult::Type::STR_HEX, "hash", "The transaction hash"},
405 {RPCResult::Type::NUM, "size", "The transaction size"},
406 {RPCResult::Type::NUM, "version", "The version"},
407 {RPCResult::Type::NUM_TIME, "locktime", "The lock time"},
409 "vin",
410 "",
411 {
413 "",
414 "",
415 {
417 "The transaction id"},
418 {RPCResult::Type::NUM, "vout", "The output number"},
420 "scriptSig",
421 "The script",
422 {
423 {RPCResult::Type::STR, "asm", "asm"},
424 {RPCResult::Type::STR_HEX, "hex", "hex"},
425 }},
426 {RPCResult::Type::NUM, "sequence",
427 "The script sequence number"},
428 }},
429 }},
431 "vout",
432 "",
433 {
435 "",
436 "",
437 {
438 {RPCResult::Type::NUM, "value",
439 "The value in " + Currency::get().ticker},
440 {RPCResult::Type::NUM, "n", "index"},
442 "scriptPubKey",
443 "",
444 {
445 {RPCResult::Type::STR, "asm", "the asm"},
446 {RPCResult::Type::STR_HEX, "hex", "the hex"},
447 {RPCResult::Type::NUM, "reqSigs",
448 "The required sigs"},
449 {RPCResult::Type::STR, "type",
450 "The type, eg 'pubkeyhash'"},
452 "addresses",
453 "",
454 {
455 {RPCResult::Type::STR, "address",
456 "bitcoin address"},
457 }},
458 }},
459 }},
460 }},
461 }},
462 RPCExamples{HelpExampleCli("decoderawtransaction", "\"hexstring\"") +
463 HelpExampleRpc("decoderawtransaction", "\"hexstring\"")},
464 [&](const RPCHelpMan &self, const Config &config,
465 const JSONRPCRequest &request) -> UniValue {
467
468 if (!DecodeHexTx(mtx, request.params[0].get_str())) {
470 "TX decode failed");
471 }
472
473 UniValue result(UniValue::VOBJ);
474 TxToUniv(CTransaction(std::move(mtx)), BlockHash(), result, false);
475
476 return result;
477 },
478 };
479}
480
482 return RPCHelpMan{
483 "decodescript",
484 "Decode a hex-encoded script.\n",
485 {
487 "the hex-encoded script"},
488 },
489 RPCResult{
491 "",
492 "",
493 {
494 {RPCResult::Type::STR, "asm", "Script public key"},
495 {RPCResult::Type::STR, "type",
496 "The output type (e.g. " + GetAllOutputTypes() + ")"},
497 {RPCResult::Type::NUM, "reqSigs", "The required signatures"},
499 "addresses",
500 "",
501 {
502 {RPCResult::Type::STR, "address", "bitcoin address"},
503 }},
504 {RPCResult::Type::STR, "p2sh",
505 "address of P2SH script wrapping this redeem script (not "
506 "returned if the script is already a P2SH)"},
507 }},
508 RPCExamples{HelpExampleCli("decodescript", "\"hexstring\"") +
509 HelpExampleRpc("decodescript", "\"hexstring\"")},
510 [&](const RPCHelpMan &self, const Config &config,
511 const JSONRPCRequest &request) -> UniValue {
513 CScript script;
514 if (request.params[0].get_str().size() > 0) {
515 std::vector<uint8_t> scriptData(
516 ParseHexV(request.params[0], "argument"));
517 script = CScript(scriptData.begin(), scriptData.end());
518 } else {
519 // Empty scripts are valid.
520 }
521
522 ScriptPubKeyToUniv(script, r, /* fIncludeHex */ false);
523
524 UniValue type;
525 type = r.find_value("type");
526
527 if (type.isStr() && type.get_str() != "scripthash") {
528 // P2SH cannot be wrapped in a P2SH. If this script is already a
529 // P2SH, don't return the address for a P2SH of the P2SH.
530 r.pushKV("p2sh", EncodeDestination(ScriptHash(script), config));
531 }
532
533 return r;
534 },
535 };
536}
537
539 return RPCHelpMan{
540 "combinerawtransaction",
541 "Combine multiple partially signed transactions into one "
542 "transaction.\n"
543 "The combined transaction may be another partially signed transaction "
544 "or a \n"
545 "fully signed transaction.",
546 {
547 {
548 "txs",
551 "The hex strings of partially signed "
552 "transactions",
553 {
554 {"hexstring", RPCArg::Type::STR_HEX,
556 "A hex-encoded raw transaction"},
557 },
558 },
559 },
561 "The hex-encoded raw transaction with signature(s)"},
562 RPCExamples{HelpExampleCli("combinerawtransaction",
563 R"('["myhex1", "myhex2", "myhex3"]')")},
564 [&](const RPCHelpMan &self, const Config &config,
565 const JSONRPCRequest &request) -> UniValue {
566 UniValue txs = request.params[0].get_array();
567 std::vector<CMutableTransaction> txVariants(txs.size());
568
569 for (unsigned int idx = 0; idx < txs.size(); idx++) {
570 if (!DecodeHexTx(txVariants[idx], txs[idx].get_str())) {
571 throw JSONRPCError(
573 strprintf("TX decode failed for tx %d", idx));
574 }
575 }
576
577 if (txVariants.empty()) {
579 "Missing transactions");
580 }
581
582 // mergedTx will end up with all the signatures; it
583 // starts as a clone of the rawtx:
584 CMutableTransaction mergedTx(txVariants[0]);
585
586 // Fetch previous transactions (inputs):
587 CCoinsView viewDummy;
588 CCoinsViewCache view(&viewDummy);
589 {
590 NodeContext &node = EnsureAnyNodeContext(request.context);
591 const CTxMemPool &mempool = EnsureMemPool(node);
593 LOCK2(cs_main, mempool.cs);
594 CCoinsViewCache &viewChain =
595 chainman.ActiveChainstate().CoinsTip();
596 CCoinsViewMemPool viewMempool(&viewChain, mempool);
597 // temporarily switch cache backend to db+mempool view
598 view.SetBackend(viewMempool);
599
600 for (const CTxIn &txin : mergedTx.vin) {
601 // Load entries from viewChain into view; can fail.
602 view.AccessCoin(txin.prevout);
603 }
604
605 // switch back to avoid locking mempool for too long
606 view.SetBackend(viewDummy);
607 }
608
609 // Use CTransaction for the constant parts of the
610 // transaction to avoid rehashing.
611 const CTransaction txConst(mergedTx);
612 // Sign what we can:
613 for (size_t i = 0; i < mergedTx.vin.size(); i++) {
614 CTxIn &txin = mergedTx.vin[i];
615 const Coin &coin = view.AccessCoin(txin.prevout);
616 if (coin.IsSpent()) {
618 "Input not found or already spent");
619 }
620 SignatureData sigdata;
621
622 const CTxOut &txout = coin.GetTxOut();
623
624 // ... and merge in other signatures:
625 for (const CMutableTransaction &txv : txVariants) {
626 if (txv.vin.size() > i) {
627 sigdata.MergeSignatureData(
628 DataFromTransaction(txv, i, txout));
629 }
630 }
633 &mergedTx, i, txout.nValue),
634 txout.scriptPubKey, sigdata);
635
636 UpdateInput(txin, sigdata);
637 }
638
639 return EncodeHexTx(CTransaction(mergedTx));
640 },
641 };
642}
643
645 return RPCHelpMan{
646 "signrawtransactionwithkey",
647 "Sign inputs for raw transaction (serialized, hex-encoded).\n"
648 "The second argument is an array of base58-encoded private\n"
649 "keys that will be the only keys used to sign the transaction.\n"
650 "The third optional argument (may be null) is an array of previous "
651 "transaction outputs that\n"
652 "this transaction depends on but may not yet be in the block chain.\n",
653 {
655 "The transaction hex string"},
656 {
657 "privkeys",
660 "The base58-encoded private keys for signing",
661 {
663 "private key in base58-encoding"},
664 },
665 },
666 {
667 "prevtxs",
670 "The previous dependent transaction outputs",
671 {
672 {
673 "",
676 "",
677 {
678 {"txid", RPCArg::Type::STR_HEX,
679 RPCArg::Optional::NO, "The transaction id"},
681 "The output number"},
682 {"scriptPubKey", RPCArg::Type::STR_HEX,
683 RPCArg::Optional::NO, "script key"},
684 {"redeemScript", RPCArg::Type::STR_HEX,
686 "(required for P2SH) redeem script"},
687 {"amount", RPCArg::Type::AMOUNT,
688 RPCArg::Optional::NO, "The amount spent"},
689 },
690 },
691 },
692 },
693 {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"ALL|FORKID"},
694 "The signature hash type. Must be one of:\n"
695 " \"ALL|FORKID\"\n"
696 " \"NONE|FORKID\"\n"
697 " \"SINGLE|FORKID\"\n"
698 " \"ALL|FORKID|ANYONECANPAY\"\n"
699 " \"NONE|FORKID|ANYONECANPAY\"\n"
700 " \"SINGLE|FORKID|ANYONECANPAY\""},
701 },
702 RPCResult{
704 "",
705 "",
706 {
708 "The hex-encoded raw transaction with signature(s)"},
709 {RPCResult::Type::BOOL, "complete",
710 "If the transaction has a complete set of signatures"},
712 "errors",
713 /* optional */ true,
714 "Script verification errors (if there are any)",
715 {
717 "",
718 "",
719 {
721 "The hash of the referenced, previous transaction"},
722 {RPCResult::Type::NUM, "vout",
723 "The index of the output to spent and used as "
724 "input"},
725 {RPCResult::Type::STR_HEX, "scriptSig",
726 "The hex-encoded signature script"},
727 {RPCResult::Type::NUM, "sequence",
728 "Script sequence number"},
729 {RPCResult::Type::STR, "error",
730 "Verification or signing error related to the "
731 "input"},
732 }},
733 }},
734 }},
736 HelpExampleCli("signrawtransactionwithkey",
737 "\"myhex\" \"[\\\"key1\\\",\\\"key2\\\"]\"") +
738 HelpExampleRpc("signrawtransactionwithkey",
739 "\"myhex\", \"[\\\"key1\\\",\\\"key2\\\"]\"")},
740 [&](const RPCHelpMan &self, const Config &config,
741 const JSONRPCRequest &request) -> UniValue {
743 if (!DecodeHexTx(mtx, request.params[0].get_str())) {
745 "TX decode failed");
746 }
747
749 const UniValue &keys = request.params[1].get_array();
750 for (size_t idx = 0; idx < keys.size(); ++idx) {
751 UniValue k = keys[idx];
752 CKey key = DecodeSecret(k.get_str());
753 if (!key.IsValid()) {
755 "Invalid private key");
756 }
757 keystore.AddKey(key);
758 }
759
760 // Fetch previous transactions (inputs):
761 std::map<COutPoint, Coin> coins;
762 for (const CTxIn &txin : mtx.vin) {
763 // Create empty map entry keyed by prevout.
764 coins[txin.prevout];
765 }
766 NodeContext &node = EnsureAnyNodeContext(request.context);
767 FindCoins(node, coins);
768
769 // Parse the prevtxs array
770 ParsePrevouts(request.params[2], &keystore, coins);
771
772 UniValue result(UniValue::VOBJ);
773 SignTransaction(mtx, &keystore, coins, request.params[3], result);
774 return result;
775 },
776 };
777}
778
780 return RPCHelpMan{
781 "decodepsbt",
782 "Return a JSON object representing the serialized, base64-encoded "
783 "partially signed Bitcoin transaction.\n",
784 {
786 "The PSBT base64 string"},
787 },
788 RPCResult{
790 "",
791 "",
792 {
794 "tx",
795 "The decoded network-serialized unsigned transaction.",
796 {
798 "The layout is the same as the output of "
799 "decoderawtransaction."},
800 }},
802 "unknown",
803 "The unknown global fields",
804 {
806 "(key-value pair) An unknown key-value pair"},
807 }},
809 "inputs",
810 "",
811 {
813 "",
814 "",
815 {
817 "utxo",
818 /* optional */ true,
819 "Transaction output for UTXOs",
820 {
821 {RPCResult::Type::NUM, "amount",
822 "The value in " + Currency::get().ticker},
824 "scriptPubKey",
825 "",
826 {
827 {RPCResult::Type::STR, "asm", "The asm"},
829 "The hex"},
830 {RPCResult::Type::STR, "type",
831 "The type, eg 'pubkeyhash'"},
832 {RPCResult::Type::STR, "address",
833 " Bitcoin address if there is one"},
834 }},
835 }},
837 "partial_signatures",
838 /* optional */ true,
839 "",
840 {
841 {RPCResult::Type::STR, "pubkey",
842 "The public key and signature that corresponds "
843 "to it."},
844 }},
845 {RPCResult::Type::STR, "sighash", /* optional */ true,
846 "The sighash type to be used"},
848 "redeem_script",
849 /* optional */ true,
850 "",
851 {
852 {RPCResult::Type::STR, "asm", "The asm"},
853 {RPCResult::Type::STR_HEX, "hex", "The hex"},
854 {RPCResult::Type::STR, "type",
855 "The type, eg 'pubkeyhash'"},
856 }},
858 "bip32_derivs",
859 /* optional */ true,
860 "",
861 {
863 "pubkey",
864 /* optional */ true,
865 "The public key with the derivation path as "
866 "the value.",
867 {
868 {RPCResult::Type::STR, "master_fingerprint",
869 "The fingerprint of the master key"},
870 {RPCResult::Type::STR, "path", "The path"},
871 }},
872 }},
874 "final_scriptsig",
875 /* optional */ true,
876 "",
877 {
878 {RPCResult::Type::STR, "asm", "The asm"},
879 {RPCResult::Type::STR, "hex", "The hex"},
880 }},
882 "unknown",
883 "The unknown global fields",
884 {
886 "(key-value pair) An unknown key-value pair"},
887 }},
888 }},
889 }},
891 "outputs",
892 "",
893 {
895 "",
896 "",
897 {
899 "redeem_script",
900 /* optional */ true,
901 "",
902 {
903 {RPCResult::Type::STR, "asm", "The asm"},
904 {RPCResult::Type::STR_HEX, "hex", "The hex"},
905 {RPCResult::Type::STR, "type",
906 "The type, eg 'pubkeyhash'"},
907 }},
909 "bip32_derivs",
910 /* optional */ true,
911 "",
912 {
914 "",
915 "",
916 {
917 {RPCResult::Type::STR, "pubkey",
918 "The public key this path corresponds to"},
919 {RPCResult::Type::STR, "master_fingerprint",
920 "The fingerprint of the master key"},
921 {RPCResult::Type::STR, "path", "The path"},
922 }},
923 }},
925 "unknown",
926 "The unknown global fields",
927 {
929 "(key-value pair) An unknown key-value pair"},
930 }},
931 }},
932 }},
933 {RPCResult::Type::STR_AMOUNT, "fee", /* optional */ true,
934 "The transaction fee paid if all UTXOs slots in the PSBT have "
935 "been filled."},
936 }},
937 RPCExamples{HelpExampleCli("decodepsbt", "\"psbt\"")},
938 [&](const RPCHelpMan &self, const Config &config,
939 const JSONRPCRequest &request) -> UniValue {
940 // Unserialize the transactions
942 std::string error;
943 if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
945 strprintf("TX decode failed %s", error));
946 }
947
948 UniValue result(UniValue::VOBJ);
949
950 // Add the decoded tx
951 UniValue tx_univ(UniValue::VOBJ);
952 TxToUniv(CTransaction(*psbtx.tx), BlockHash(), tx_univ, false);
953 result.pushKV("tx", tx_univ);
954
955 // Unknown data
956 if (psbtx.unknown.size() > 0) {
957 UniValue unknowns(UniValue::VOBJ);
958 for (auto entry : psbtx.unknown) {
959 unknowns.pushKV(HexStr(entry.first), HexStr(entry.second));
960 }
961 result.pushKV("unknown", unknowns);
962 }
963
964 // inputs
965 Amount total_in = Amount::zero();
966 bool have_all_utxos = true;
967 UniValue inputs(UniValue::VARR);
968 for (size_t i = 0; i < psbtx.inputs.size(); ++i) {
969 const PSBTInput &input = psbtx.inputs[i];
971 // UTXOs
972 if (!input.utxo.IsNull()) {
973 const CTxOut &txout = input.utxo;
974
976
977 out.pushKV("amount", txout.nValue);
978 if (MoneyRange(txout.nValue) &&
979 MoneyRange(total_in + txout.nValue)) {
980 total_in += txout.nValue;
981 } else {
982 // Hack to just not show fee later
983 have_all_utxos = false;
984 }
985
987 ScriptToUniv(txout.scriptPubKey, o, true);
988 out.pushKV("scriptPubKey", o);
989 in.pushKV("utxo", out);
990 } else {
991 have_all_utxos = false;
992 }
993
994 // Partial sigs
995 if (!input.partial_sigs.empty()) {
996 UniValue partial_sigs(UniValue::VOBJ);
997 for (const auto &sig : input.partial_sigs) {
998 partial_sigs.pushKV(HexStr(sig.second.first),
999 HexStr(sig.second.second));
1000 }
1001 in.pushKV("partial_signatures", partial_sigs);
1002 }
1003
1004 // Sighash
1005 uint8_t sighashbyte =
1006 input.sighash_type.getRawSigHashType() & 0xff;
1007 if (sighashbyte > 0) {
1008 in.pushKV("sighash", SighashToStr(sighashbyte));
1009 }
1010
1011 // Redeem script
1012 if (!input.redeem_script.empty()) {
1014 ScriptToUniv(input.redeem_script, r, false);
1015 in.pushKV("redeem_script", r);
1016 }
1017
1018 // keypaths
1019 if (!input.hd_keypaths.empty()) {
1020 UniValue keypaths(UniValue::VARR);
1021 for (auto entry : input.hd_keypaths) {
1022 UniValue keypath(UniValue::VOBJ);
1023 keypath.pushKV("pubkey", HexStr(entry.first));
1024
1025 keypath.pushKV(
1026 "master_fingerprint",
1027 strprintf("%08x",
1028 ReadBE32(entry.second.fingerprint)));
1029 keypath.pushKV("path",
1030 WriteHDKeypath(entry.second.path));
1031 keypaths.push_back(keypath);
1032 }
1033 in.pushKV("bip32_derivs", keypaths);
1034 }
1035
1036 // Final scriptSig
1037 if (!input.final_script_sig.empty()) {
1038 UniValue scriptsig(UniValue::VOBJ);
1039 scriptsig.pushKV(
1040 "asm", ScriptToAsmStr(input.final_script_sig, true));
1041 scriptsig.pushKV("hex", HexStr(input.final_script_sig));
1042 in.pushKV("final_scriptSig", scriptsig);
1043 }
1044
1045 // Unknown data
1046 if (input.unknown.size() > 0) {
1047 UniValue unknowns(UniValue::VOBJ);
1048 for (auto entry : input.unknown) {
1049 unknowns.pushKV(HexStr(entry.first),
1050 HexStr(entry.second));
1051 }
1052 in.pushKV("unknown", unknowns);
1053 }
1054
1055 inputs.push_back(in);
1056 }
1057 result.pushKV("inputs", inputs);
1058
1059 // outputs
1060 Amount output_value = Amount::zero();
1061 UniValue outputs(UniValue::VARR);
1062 for (size_t i = 0; i < psbtx.outputs.size(); ++i) {
1063 const PSBTOutput &output = psbtx.outputs[i];
1065 // Redeem script
1066 if (!output.redeem_script.empty()) {
1068 ScriptToUniv(output.redeem_script, r, false);
1069 out.pushKV("redeem_script", r);
1070 }
1071
1072 // keypaths
1073 if (!output.hd_keypaths.empty()) {
1074 UniValue keypaths(UniValue::VARR);
1075 for (auto entry : output.hd_keypaths) {
1076 UniValue keypath(UniValue::VOBJ);
1077 keypath.pushKV("pubkey", HexStr(entry.first));
1078 keypath.pushKV(
1079 "master_fingerprint",
1080 strprintf("%08x",
1081 ReadBE32(entry.second.fingerprint)));
1082 keypath.pushKV("path",
1083 WriteHDKeypath(entry.second.path));
1084 keypaths.push_back(keypath);
1085 }
1086 out.pushKV("bip32_derivs", keypaths);
1087 }
1088
1089 // Unknown data
1090 if (output.unknown.size() > 0) {
1091 UniValue unknowns(UniValue::VOBJ);
1092 for (auto entry : output.unknown) {
1093 unknowns.pushKV(HexStr(entry.first),
1094 HexStr(entry.second));
1095 }
1096 out.pushKV("unknown", unknowns);
1097 }
1098
1099 outputs.push_back(out);
1100
1101 // Fee calculation
1102 if (MoneyRange(psbtx.tx->vout[i].nValue) &&
1103 MoneyRange(output_value + psbtx.tx->vout[i].nValue)) {
1104 output_value += psbtx.tx->vout[i].nValue;
1105 } else {
1106 // Hack to just not show fee later
1107 have_all_utxos = false;
1108 }
1109 }
1110 result.pushKV("outputs", outputs);
1111 if (have_all_utxos) {
1112 result.pushKV("fee", total_in - output_value);
1113 }
1114
1115 return result;
1116 },
1117 };
1118}
1119
1121 return RPCHelpMan{
1122 "combinepsbt",
1123 "Combine multiple partially signed Bitcoin transactions into one "
1124 "transaction.\n"
1125 "Implements the Combiner role.\n",
1126 {
1127 {
1128 "txs",
1131 "The base64 strings of partially signed transactions",
1132 {
1134 "A base64 string of a PSBT"},
1135 },
1136 },
1137 },
1139 "The base64-encoded partially signed transaction"},
1141 "combinepsbt", R"('["mybase64_1", "mybase64_2", "mybase64_3"]')")},
1142 [&](const RPCHelpMan &self, const Config &config,
1143 const JSONRPCRequest &request) -> UniValue {
1144 // Unserialize the transactions
1145 std::vector<PartiallySignedTransaction> psbtxs;
1146 UniValue txs = request.params[0].get_array();
1147 if (txs.empty()) {
1149 "Parameter 'txs' cannot be empty");
1150 }
1151 for (size_t i = 0; i < txs.size(); ++i) {
1153 std::string error;
1154 if (!DecodeBase64PSBT(psbtx, txs[i].get_str(), error)) {
1156 strprintf("TX decode failed %s", error));
1157 }
1158 psbtxs.push_back(psbtx);
1159 }
1160
1161 PartiallySignedTransaction merged_psbt;
1162 const TransactionError error = CombinePSBTs(merged_psbt, psbtxs);
1163 if (error != TransactionError::OK) {
1165 }
1166
1168 ssTx << merged_psbt;
1169 return EncodeBase64(ssTx);
1170 },
1171 };
1172}
1173
1175 return RPCHelpMan{
1176 "finalizepsbt",
1177 "Finalize the inputs of a PSBT. If the transaction is fully signed, it "
1178 "will produce a\n"
1179 "network serialized transaction which can be broadcast with "
1180 "sendrawtransaction. Otherwise a PSBT will be\n"
1181 "created which has the final_scriptSigfields filled for inputs that "
1182 "are complete.\n"
1183 "Implements the Finalizer and Extractor roles.\n",
1184 {
1186 "A base64 string of a PSBT"},
1187 {"extract", RPCArg::Type::BOOL, RPCArg::Default{true},
1188 "If true and the transaction is complete,\n"
1189 " extract and return the complete "
1190 "transaction in normal network serialization instead of the "
1191 "PSBT."},
1192 },
1194 "",
1195 "",
1196 {
1197 {RPCResult::Type::STR, "psbt",
1198 "The base64-encoded partially signed transaction if not "
1199 "extracted"},
1201 "The hex-encoded network transaction if extracted"},
1202 {RPCResult::Type::BOOL, "complete",
1203 "If the transaction has a complete set of signatures"},
1204 }},
1205 RPCExamples{HelpExampleCli("finalizepsbt", "\"psbt\"")},
1206 [&](const RPCHelpMan &self, const Config &config,
1207 const JSONRPCRequest &request) -> UniValue {
1208 // Unserialize the transactions
1210 std::string error;
1211 if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
1213 strprintf("TX decode failed %s", error));
1214 }
1215
1216 bool extract =
1217 request.params[1].isNull() ||
1218 (!request.params[1].isNull() && request.params[1].get_bool());
1219
1221 bool complete = FinalizeAndExtractPSBT(psbtx, mtx);
1222
1223 UniValue result(UniValue::VOBJ);
1225 std::string result_str;
1226
1227 if (complete && extract) {
1228 ssTx << mtx;
1229 result_str = HexStr(ssTx);
1230 result.pushKV("hex", result_str);
1231 } else {
1232 ssTx << psbtx;
1233 result_str = EncodeBase64(ssTx.str());
1234 result.pushKV("psbt", result_str);
1235 }
1236 result.pushKV("complete", complete);
1237
1238 return result;
1239 },
1240 };
1241}
1242
1244 return RPCHelpMan{
1245 "createpsbt",
1246 "Creates a transaction in the Partially Signed Transaction format.\n"
1247 "Implements the Creator role.\n",
1248 {
1249 {
1250 "inputs",
1253 "The json objects",
1254 {
1255 {
1256 "",
1259 "",
1260 {
1261 {"txid", RPCArg::Type::STR_HEX,
1262 RPCArg::Optional::NO, "The transaction id"},
1264 "The output number"},
1265 {"sequence", RPCArg::Type::NUM,
1266 RPCArg::DefaultHint{"depends on the value of the "
1267 "'locktime' argument"},
1268 "The sequence number"},
1269 },
1270 },
1271 },
1272 },
1273 {"outputs",
1276 "The outputs (key-value pairs), where none of "
1277 "the keys are duplicated.\n"
1278 "That is, each address can only appear once and there can only "
1279 "be one 'data' object.\n"
1280 "For compatibility reasons, a dictionary, which holds the "
1281 "key-value pairs directly, is also\n"
1282 " accepted as second parameter.",
1283 {
1284 {
1285 "",
1288 "",
1289 {
1291 "A key-value pair. The key (string) is the "
1292 "bitcoin address, the value (float or string) is "
1293 "the amount in " +
1295 },
1296 },
1297 {
1298 "",
1301 "",
1302 {
1304 "A key-value pair. The key must be \"data\", the "
1305 "value is hex-encoded data"},
1306 },
1307 },
1308 },
1310 {"locktime", RPCArg::Type::NUM, RPCArg::Default{0},
1311 "Raw locktime. Non-0 value also locktime-activates inputs"},
1312 },
1314 "The resulting raw transaction (base64-encoded string)"},
1316 "createpsbt", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
1317 "\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"")},
1318 [&](const RPCHelpMan &self, const Config &config,
1319 const JSONRPCRequest &request) -> UniValue {
1320 CMutableTransaction rawTx =
1321 ConstructTransaction(config.GetChainParams(), request.params[0],
1322 request.params[1], request.params[2]);
1323
1324 // Make a blank psbt
1326 psbtx.tx = rawTx;
1327 for (size_t i = 0; i < rawTx.vin.size(); ++i) {
1328 psbtx.inputs.push_back(PSBTInput());
1329 }
1330 for (size_t i = 0; i < rawTx.vout.size(); ++i) {
1331 psbtx.outputs.push_back(PSBTOutput());
1332 }
1333
1334 // Serialize the PSBT
1336 ssTx << psbtx;
1337
1338 return EncodeBase64(ssTx);
1339 },
1340 };
1341}
1342
1344 return RPCHelpMan{
1345 "converttopsbt",
1346 "Converts a network serialized transaction to a PSBT. "
1347 "This should be used only with createrawtransaction and "
1348 "fundrawtransaction\n"
1349 "createpsbt and walletcreatefundedpsbt should be used for new "
1350 "applications.\n",
1351 {
1353 "The hex string of a raw transaction"},
1354 {"permitsigdata", RPCArg::Type::BOOL, RPCArg::Default{false},
1355 "If true, any signatures in the input will be discarded and "
1356 "conversion.\n"
1357 " will continue. If false, RPC will "
1358 "fail if any signatures are present."},
1359 },
1361 "The resulting raw transaction (base64-encoded string)"},
1363 "\nCreate a transaction\n" +
1364 HelpExampleCli("createrawtransaction",
1365 "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
1366 "\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") +
1367 "\nConvert the transaction to a PSBT\n" +
1368 HelpExampleCli("converttopsbt", "\"rawtransaction\"")},
1369 [&](const RPCHelpMan &self, const Config &config,
1370 const JSONRPCRequest &request) -> UniValue {
1371 // parse hex string from parameter
1373 bool permitsigdata = request.params[1].isNull()
1374 ? false
1375 : request.params[1].get_bool();
1376 if (!DecodeHexTx(tx, request.params[0].get_str())) {
1378 "TX decode failed");
1379 }
1380
1381 // Remove all scriptSigs from inputs
1382 for (CTxIn &input : tx.vin) {
1383 if (!input.scriptSig.empty() && !permitsigdata) {
1385 "Inputs must not have scriptSigs");
1386 }
1387 input.scriptSig.clear();
1388 }
1389
1390 // Make a blank psbt
1392 psbtx.tx = tx;
1393 for (size_t i = 0; i < tx.vin.size(); ++i) {
1394 psbtx.inputs.push_back(PSBTInput());
1395 }
1396 for (size_t i = 0; i < tx.vout.size(); ++i) {
1397 psbtx.outputs.push_back(PSBTOutput());
1398 }
1399
1400 // Serialize the PSBT
1402 ssTx << psbtx;
1403
1404 return EncodeBase64(ssTx);
1405 },
1406 };
1407}
1408
1410 return RPCHelpMan{
1411 "utxoupdatepsbt",
1412 "Updates all inputs and outputs in a PSBT with data from output "
1413 "descriptors, the UTXO set or the mempool.\n",
1414 {
1416 "A base64 string of a PSBT"},
1417 {"descriptors",
1420 "An array of either strings or objects",
1421 {
1423 "An output descriptor"},
1424 {"",
1427 "An object with an output descriptor and extra information",
1428 {
1430 "An output descriptor"},
1431 {"range", RPCArg::Type::RANGE, RPCArg::Default{1000},
1432 "Up to what index HD chains should be explored (either "
1433 "end or [begin,end])"},
1434 }},
1435 }},
1436 },
1438 "The base64-encoded partially signed transaction with inputs "
1439 "updated"},
1440 RPCExamples{HelpExampleCli("utxoupdatepsbt", "\"psbt\"")},
1441 [&](const RPCHelpMan &self, const Config &config,
1442 const JSONRPCRequest &request) -> UniValue {
1443 // Unserialize the transactions
1445 std::string error;
1446 if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
1448 strprintf("TX decode failed %s", error));
1449 }
1450
1451 // Parse descriptors, if any.
1452 FlatSigningProvider provider;
1453 if (!request.params[1].isNull()) {
1454 auto descs = request.params[1].get_array();
1455 for (size_t i = 0; i < descs.size(); ++i) {
1456 EvalDescriptorStringOrObject(descs[i], provider);
1457 }
1458 }
1459 // We don't actually need private keys further on; hide them as a
1460 // precaution.
1461 HidingSigningProvider public_provider(&provider, /* nosign */ true,
1462 /* nobip32derivs */ false);
1463
1464 // Fetch previous transactions (inputs):
1465 CCoinsView viewDummy;
1466 CCoinsViewCache view(&viewDummy);
1467 {
1468 NodeContext &node = EnsureAnyNodeContext(request.context);
1469 const CTxMemPool &mempool = EnsureMemPool(node);
1471 LOCK2(cs_main, mempool.cs);
1472 CCoinsViewCache &viewChain =
1473 chainman.ActiveChainstate().CoinsTip();
1474 CCoinsViewMemPool viewMempool(&viewChain, mempool);
1475 // temporarily switch cache backend to db+mempool view
1476 view.SetBackend(viewMempool);
1477
1478 for (const CTxIn &txin : psbtx.tx->vin) {
1479 // Load entries from viewChain into view; can fail.
1480 view.AccessCoin(txin.prevout);
1481 }
1482
1483 // switch back to avoid locking mempool for too long
1484 view.SetBackend(viewDummy);
1485 }
1486
1487 // Fill the inputs
1488 for (size_t i = 0; i < psbtx.tx->vin.size(); ++i) {
1489 PSBTInput &input = psbtx.inputs.at(i);
1490
1491 if (!input.utxo.IsNull()) {
1492 continue;
1493 }
1494
1495 // Update script/keypath information using descriptor data.
1496 // Note that SignPSBTInput does a lot more than just
1497 // constructing ECDSA signatures we don't actually care about
1498 // those here, in fact.
1499 SignPSBTInput(public_provider, psbtx, i,
1500 /* sighash_type */ SigHashType().withForkId());
1501 }
1502
1503 // Update script/keypath information using descriptor data.
1504 for (unsigned int i = 0; i < psbtx.tx->vout.size(); ++i) {
1505 UpdatePSBTOutput(public_provider, psbtx, i);
1506 }
1507
1509 ssTx << psbtx;
1510 return EncodeBase64(ssTx);
1511 },
1512 };
1513}
1514
1516 return RPCHelpMan{
1517 "joinpsbts",
1518 "Joins multiple distinct PSBTs with different inputs and outputs "
1519 "into one PSBT with inputs and outputs from all of the PSBTs\n"
1520 "No input in any of the PSBTs can be in more than one of the PSBTs.\n",
1521 {{"txs",
1524 "The base64 strings of partially signed transactions",
1526 "A base64 string of a PSBT"}}}},
1528 "The base64-encoded partially signed transaction"},
1529 RPCExamples{HelpExampleCli("joinpsbts", "\"psbt\"")},
1530 [&](const RPCHelpMan &self, const Config &config,
1531 const JSONRPCRequest &request) -> UniValue {
1532 // Unserialize the transactions
1533 std::vector<PartiallySignedTransaction> psbtxs;
1534 UniValue txs = request.params[0].get_array();
1535
1536 if (txs.size() <= 1) {
1537 throw JSONRPCError(
1539 "At least two PSBTs are required to join PSBTs.");
1540 }
1541
1542 uint32_t best_version = 1;
1543 uint32_t best_locktime = 0xffffffff;
1544 for (size_t i = 0; i < txs.size(); ++i) {
1546 std::string error;
1547 if (!DecodeBase64PSBT(psbtx, txs[i].get_str(), error)) {
1549 strprintf("TX decode failed %s", error));
1550 }
1551 psbtxs.push_back(psbtx);
1552 // Choose the highest version number
1553 if (static_cast<uint32_t>(psbtx.tx->nVersion) > best_version) {
1554 best_version = static_cast<uint32_t>(psbtx.tx->nVersion);
1555 }
1556 // Choose the lowest lock time
1557 if (psbtx.tx->nLockTime < best_locktime) {
1558 best_locktime = psbtx.tx->nLockTime;
1559 }
1560 }
1561
1562 // Create a blank psbt where everything will be added
1563 PartiallySignedTransaction merged_psbt;
1564 merged_psbt.tx = CMutableTransaction();
1565 merged_psbt.tx->nVersion = static_cast<int32_t>(best_version);
1566 merged_psbt.tx->nLockTime = best_locktime;
1567
1568 // Merge
1569 for (auto &psbt : psbtxs) {
1570 for (size_t i = 0; i < psbt.tx->vin.size(); ++i) {
1571 if (!merged_psbt.AddInput(psbt.tx->vin[i],
1572 psbt.inputs[i])) {
1573 throw JSONRPCError(
1575 strprintf("Input %s:%d exists in multiple PSBTs",
1576 psbt.tx->vin[i]
1577 .prevout.GetTxId()
1578 .ToString()
1579 .c_str(),
1580 psbt.tx->vin[i].prevout.GetN()));
1581 }
1582 }
1583 for (size_t i = 0; i < psbt.tx->vout.size(); ++i) {
1584 merged_psbt.AddOutput(psbt.tx->vout[i], psbt.outputs[i]);
1585 }
1586 merged_psbt.unknown.insert(psbt.unknown.begin(),
1587 psbt.unknown.end());
1588 }
1589
1590 // Generate list of shuffled indices for shuffling inputs and
1591 // outputs of the merged PSBT
1592 std::vector<int> input_indices(merged_psbt.inputs.size());
1593 std::iota(input_indices.begin(), input_indices.end(), 0);
1594 std::vector<int> output_indices(merged_psbt.outputs.size());
1595 std::iota(output_indices.begin(), output_indices.end(), 0);
1596
1597 // Shuffle input and output indices lists
1598 Shuffle(input_indices.begin(), input_indices.end(),
1600 Shuffle(output_indices.begin(), output_indices.end(),
1602
1603 PartiallySignedTransaction shuffled_psbt;
1604 shuffled_psbt.tx = CMutableTransaction();
1605 shuffled_psbt.tx->nVersion = merged_psbt.tx->nVersion;
1606 shuffled_psbt.tx->nLockTime = merged_psbt.tx->nLockTime;
1607 for (int i : input_indices) {
1608 shuffled_psbt.AddInput(merged_psbt.tx->vin[i],
1609 merged_psbt.inputs[i]);
1610 }
1611 for (int i : output_indices) {
1612 shuffled_psbt.AddOutput(merged_psbt.tx->vout[i],
1613 merged_psbt.outputs[i]);
1614 }
1615 shuffled_psbt.unknown.insert(merged_psbt.unknown.begin(),
1616 merged_psbt.unknown.end());
1617
1619 ssTx << shuffled_psbt;
1620 return EncodeBase64(ssTx);
1621 },
1622 };
1623}
1624
1626 return RPCHelpMan{
1627 "analyzepsbt",
1628 "Analyzes and provides information about the current status of a "
1629 "PSBT and its inputs\n",
1631 "A base64 string of a PSBT"}},
1632 RPCResult{
1634 "",
1635 "",
1636 {
1638 "inputs",
1639 "",
1640 {
1642 "",
1643 "",
1644 {
1645 {RPCResult::Type::BOOL, "has_utxo",
1646 "Whether a UTXO is provided"},
1647 {RPCResult::Type::BOOL, "is_final",
1648 "Whether the input is finalized"},
1650 "missing",
1651 /* optional */ true,
1652 "Things that are missing that are required to "
1653 "complete this input",
1654 {
1656 "pubkeys",
1657 /* optional */ true,
1658 "",
1659 {
1660 {RPCResult::Type::STR_HEX, "keyid",
1661 "Public key ID, hash160 of the public "
1662 "key, of a public key whose BIP 32 "
1663 "derivation path is missing"},
1664 }},
1666 "signatures",
1667 /* optional */ true,
1668 "",
1669 {
1670 {RPCResult::Type::STR_HEX, "keyid",
1671 "Public key ID, hash160 of the public "
1672 "key, of a public key whose signature is "
1673 "missing"},
1674 }},
1675 {RPCResult::Type::STR_HEX, "redeemscript",
1676 /* optional */ true,
1677 "Hash160 of the redeemScript that is missing"},
1678 }},
1679 {RPCResult::Type::STR, "next", /* optional */ true,
1680 "Role of the next person that this input needs to "
1681 "go to"},
1682 }},
1683 }},
1684 {RPCResult::Type::NUM, "estimated_vsize", /* optional */ true,
1685 "Estimated vsize of the final signed transaction"},
1686 {RPCResult::Type::STR_AMOUNT, "estimated_feerate",
1687 /* optional */ true,
1688 "Estimated feerate of the final signed transaction in " +
1690 "/kB. Shown only if all UTXO slots in the PSBT have been "
1691 "filled"},
1692 {RPCResult::Type::STR_AMOUNT, "fee", /* optional */ true,
1693 "The transaction fee paid. Shown only if all UTXO slots in "
1694 "the PSBT have been filled"},
1695 {RPCResult::Type::STR, "next",
1696 "Role of the next person that this psbt needs to go to"},
1697 {RPCResult::Type::STR, "error", /* optional */ true,
1698 "Error message (if there is one)"},
1699 }},
1700 RPCExamples{HelpExampleCli("analyzepsbt", "\"psbt\"")},
1701 [&](const RPCHelpMan &self, const Config &config,
1702 const JSONRPCRequest &request) -> UniValue {
1703 // Unserialize the transaction
1705 std::string error;
1706 if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
1708 strprintf("TX decode failed %s", error));
1709 }
1710
1711 PSBTAnalysis psbta = AnalyzePSBT(psbtx);
1712
1713 UniValue result(UniValue::VOBJ);
1714 UniValue inputs_result(UniValue::VARR);
1715 for (const auto &input : psbta.inputs) {
1716 UniValue input_univ(UniValue::VOBJ);
1717 UniValue missing(UniValue::VOBJ);
1718
1719 input_univ.pushKV("has_utxo", input.has_utxo);
1720 input_univ.pushKV("is_final", input.is_final);
1721 input_univ.pushKV("next", PSBTRoleName(input.next));
1722
1723 if (!input.missing_pubkeys.empty()) {
1724 UniValue missing_pubkeys_univ(UniValue::VARR);
1725 for (const CKeyID &pubkey : input.missing_pubkeys) {
1726 missing_pubkeys_univ.push_back(HexStr(pubkey));
1727 }
1728 missing.pushKV("pubkeys", missing_pubkeys_univ);
1729 }
1730 if (!input.missing_redeem_script.IsNull()) {
1731 missing.pushKV("redeemscript",
1732 HexStr(input.missing_redeem_script));
1733 }
1734 if (!input.missing_sigs.empty()) {
1735 UniValue missing_sigs_univ(UniValue::VARR);
1736 for (const CKeyID &pubkey : input.missing_sigs) {
1737 missing_sigs_univ.push_back(HexStr(pubkey));
1738 }
1739 missing.pushKV("signatures", missing_sigs_univ);
1740 }
1741 if (!missing.getKeys().empty()) {
1742 input_univ.pushKV("missing", missing);
1743 }
1744 inputs_result.push_back(input_univ);
1745 }
1746 if (!inputs_result.empty()) {
1747 result.pushKV("inputs", inputs_result);
1748 }
1749 if (psbta.estimated_vsize != std::nullopt) {
1750 result.pushKV("estimated_vsize", (int)*psbta.estimated_vsize);
1751 }
1752 if (psbta.estimated_feerate != std::nullopt) {
1753 result.pushKV("estimated_feerate",
1754 psbta.estimated_feerate->GetFeePerK());
1755 }
1756 if (psbta.fee != std::nullopt) {
1757 result.pushKV("fee", *psbta.fee);
1758 }
1759 result.pushKV("next", PSBTRoleName(psbta.next));
1760 if (!psbta.error.empty()) {
1761 result.pushKV("error", psbta.error);
1762 }
1763
1764 return result;
1765 },
1766 };
1767}
1768
1770 return RPCHelpMan{
1771 "gettransactionstatus",
1772 "Return the current pool a transaction belongs to\n",
1773 {
1775 "The transaction id"},
1776 },
1777 RPCResult{
1779 "",
1780 "",
1781 {
1782 {RPCResult::Type::STR, "pool",
1783 "In which pool the transaction is currently located, "
1784 "either none, mempool, orphanage or conflicting"},
1785 {RPCResult::Type::STR, "block",
1786 "If the transaction is mined, this is the blockhash of the "
1787 "mining block, otherwise \"none\". This field is only "
1788 "present if -txindex is enabled."},
1789 }},
1790 RPCExamples{HelpExampleCli("gettransactionstatus", "\"txid\"")},
1791 [&](const RPCHelpMan &self, const Config &config,
1792 const JSONRPCRequest &request) -> UniValue {
1793 const NodeContext &node = EnsureAnyNodeContext(request.context);
1794 CTxMemPool &mempool = EnsureMemPool(node);
1795
1796 TxId txid = TxId(ParseHashV(request.params[0], "parameter 1"));
1797
1799
1800 if (mempool.exists(txid)) {
1801 ret.pushKV("pool", "mempool");
1802 } else if (mempool.withOrphanage(
1803 [&txid](const TxOrphanage &orphanage) {
1804 return orphanage.HaveTx(txid);
1805 })) {
1806 ret.pushKV("pool", "orphanage");
1807 } else if (mempool.withConflicting(
1808 [&txid](const TxConflicting &conflicting) {
1809 return conflicting.HaveTx(txid);
1810 })) {
1811 ret.pushKV("pool", "conflicting");
1812 } else {
1813 ret.pushKV("pool", "none");
1814 }
1815
1816 if (g_txindex) {
1817 if (!g_txindex->BlockUntilSyncedToCurrentChain()) {
1818 throw JSONRPCError(
1820 "Blockchain transactions are still in the process of "
1821 "being indexed");
1822 }
1823
1824 CTransactionRef tx;
1825 BlockHash blockhash;
1826 if (g_txindex->FindTx(txid, blockhash, tx)) {
1827 ret.pushKV("block", blockhash.GetHex());
1828 } else {
1829 ret.pushKV("block", "none");
1830 }
1831 }
1832
1833 return ret;
1834 },
1835 };
1836}
1837
1839 // clang-format off
1840 static const CRPCCommand commands[] = {
1841 // category actor (function)
1842 // ------------------ ----------------------
1843 { "rawtransactions", getrawtransaction, },
1844 { "rawtransactions", createrawtransaction, },
1845 { "rawtransactions", decoderawtransaction, },
1846 { "rawtransactions", decodescript, },
1847 { "rawtransactions", combinerawtransaction, },
1848 { "rawtransactions", signrawtransactionwithkey, },
1849 { "rawtransactions", decodepsbt, },
1850 { "rawtransactions", combinepsbt, },
1851 { "rawtransactions", finalizepsbt, },
1852 { "rawtransactions", createpsbt, },
1853 { "rawtransactions", converttopsbt, },
1854 { "rawtransactions", utxoupdatepsbt, },
1855 { "rawtransactions", joinpsbts, },
1856 { "rawtransactions", analyzepsbt, },
1857 { "rawtransactions", gettransactionstatus, },
1858 };
1859 // clang-format on
1860 for (const auto &c : commands) {
1861 t.appendCommand(c.name, &c);
1862 }
1863}
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:85
const CBlock & GenesisBlock() const
Definition: chainparams.h:110
void SetBackend(CCoinsView &viewIn)
Definition: coins.cpp:47
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:221
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:163
CCoinsView that brings transactions from a mempool into view.
Definition: txmempool.h:635
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:177
std::string str() const
Definition: streams.h:212
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:327
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition: txmempool.h:214
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
Definition: txmempool.h:310
bool exists(const TxId &txid) const
Definition: txmempool.h:521
auto withOrphanage(Callable &&func) const EXCLUSIVE_LOCKS_REQUIRED(!cs_orphanage)
Definition: txmempool.h:578
auto withConflicting(Callable &&func) const EXCLUSIVE_LOCKS_REQUIRED(!cs_conflicting)
Definition: txmempool.h:586
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:700
CChain m_chain
The current chain of blockheaders we consult and build on.
Definition: validation.h:799
node::BlockManager & m_blockman
Reference to a BlockManager instance which itself is shared across all Chainstate instances.
Definition: validation.h:757
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
Definition: validation.h:1149
SnapshotCompletionResult MaybeCompleteSnapshotValidation(std::function< void(bilingual_str)> shutdown_fnc=[](bilingual_str msg) { AbortNode(msg.original, msg);}) 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:1397
CChain & ActiveChain() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
Definition: validation.h:1398
node::BlockManager m_blockman
A single BlockManager instance is shared across each constructed chainstate to avoid duplicating bloc...
Definition: validation.h:1287
A UTXO entry.
Definition: coins.h:28
CTxOut & GetTxOut()
Definition: coins.h:49
bool IsSpent() const
Definition: coins.h:47
Definition: config.h:19
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:175
void TxToUniv(const CTransaction &tx, const BlockHash &hashBlock, UniValue &entry, bool include_hex=true, int serialize_flags=0, const CTxUndo *txundo=nullptr)
Definition: core_write.cpp:217
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:190
bool DecodeHexTx(CMutableTransaction &tx, const std::string &strHexTx)
Definition: core_read.cpp:197
std::string ScriptToAsmStr(const CScript &script, const bool fAttemptSighashDecode=false)
Create the assembly string representation of a CScript object.
Definition: core_write.cpp:106
std::string EncodeHexTx(const CTransaction &tx, const int serializeFlags=0)
Definition: core_write.cpp:169
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
bool error(const char *fmt, const Args &...args)
Definition: logging.h:263
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
TransactionError BroadcastTransaction(const NodeContext &node, const CTransactionRef tx, std::string &err_string, const Amount max_tx_fee, bool relay, bool wait_callback)
Submit a transaction to the mempool and (optionally) relay it to all P2P peers.
Definition: transaction.cpp:37
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:511
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:291
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:152
int RPCSerializationFlags()
Retrieves any serialization flags requested in command line argument.
Definition: server.cpp:679
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:46
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