Bitcoin ABC 0.34.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/solver.h>
34#include <txmempool.h>
35#include <uint256.h>
36#include <util/bip32.h>
37#include <util/check.h>
38#include <util/strencodings.h>
39#include <util/string.h>
40#include <util/vector.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
84// Update PSBT with information from the mempool, the UTXO set, and the provided
85// descriptors
86PartiallySignedTransaction ProcessPSBT(const std::string &psbt_string,
87 const std::any &context,
88 const HidingSigningProvider &provider) {
89 // Unserialize the transactions
91 std::string error;
92 if (!DecodeBase64PSBT(psbtx, psbt_string, error)) {
94 strprintf("TX decode failed %s", error));
95 }
96
97 // Fetch previous transactions (inputs):
98 CCoinsView viewDummy;
99 CCoinsViewCache view(&viewDummy);
100 {
102 const CTxMemPool &mempool = EnsureMemPool(node);
104 LOCK2(cs_main, mempool.cs);
105 CCoinsViewCache &viewChain = chainman.ActiveChainstate().CoinsTip();
106 CCoinsViewMemPool viewMempool(&viewChain, mempool);
107 // temporarily switch cache backend to db+mempool view
108 view.SetBackend(viewMempool);
109
110 for (const CTxIn &txin : psbtx.tx->vin) {
111 // Load entries from viewChain into view; can fail.
112 view.AccessCoin(txin.prevout);
113 }
114
115 // switch back to avoid locking mempool for too long
116 view.SetBackend(viewDummy);
117 }
118
119 // Fill the inputs
120 for (size_t i = 0; i < psbtx.tx->vin.size(); ++i) {
121 PSBTInput &input = psbtx.inputs.at(i);
122
123 if (!input.utxo.IsNull()) {
124 continue;
125 }
126
127 // Update script/keypath information using descriptor data.
128 // Note that SignPSBTInput does a lot more than just
129 // constructing ECDSA signatures we don't actually care about
130 // those here, in fact.
131 SignPSBTInput(provider, psbtx, i,
132 /* sighash_type */ SigHashType().withForkId());
133 }
134
135 // Update script/keypath information using descriptor data.
136 for (unsigned int i = 0; i < psbtx.tx->vout.size(); ++i) {
137 UpdatePSBTOutput(provider, psbtx, i);
138 }
139 return psbtx;
140}
141
143 return RPCHelpMan{
144 "getrawtransaction",
145 "Return the raw transaction data.\n"
146 "\nBy default, this call only returns a transaction if it is in the "
147 "mempool. If -txindex is enabled\n"
148 "and no blockhash argument is passed, it will return the transaction "
149 "if it is in the mempool or any block.\n"
150 "If a blockhash argument is passed, it will return the transaction if\n"
151 "the specified block is available and the transaction is in that "
152 "block.\n"
153 "\nIf verbose is 'true', returns an Object with information about "
154 "'txid'.\n"
155 "If verbose is 'false' or omitted, returns a string that is "
156 "serialized, hex-encoded data for 'txid'.",
157 {
159 "The transaction id"},
160 // Verbose is a boolean, but we accept an int for backward
161 // compatibility
162 {"verbose", RPCArg::Type::BOOL, RPCArg::Default{false},
163 "If false, return a string, otherwise return a json object",
166 "The block in which to look for the transaction"},
167 },
168 {
169 RPCResult{"if verbose is not set or set to false",
170 RPCResult::Type::STR, "data",
171 "The serialized, hex-encoded data for 'txid'"},
172 RPCResult{
173 "if verbose is set to true",
175 "",
176 "",
177 Cat<std::vector<RPCResult>>(
178 {
179 {RPCResult::Type::BOOL, "in_active_chain",
180 "Whether specified block is in the active chain or "
181 "not "
182 "(only present with explicit \"blockhash\" argument)"},
183 {RPCResult::Type::STR_HEX, "blockhash",
184 "the block hash"},
185 {RPCResult::Type::NUM, "confirmations",
186 "The confirmations"},
187 {RPCResult::Type::NUM_TIME, "blocktime",
188 "The block time expressed in " + UNIX_EPOCH_TIME},
189 {RPCResult::Type::NUM, "time", "Same as \"blocktime\""},
191 "The serialized, hex-encoded data for 'txid'"},
192 },
193 DecodeTxDoc(/*txid_field_doc=*/"The transaction id (same "
194 "as provided)",
195 /*wallet=*/false)),
196 },
197 },
198 RPCExamples{HelpExampleCli("getrawtransaction", "\"mytxid\"") +
199 HelpExampleCli("getrawtransaction", "\"mytxid\" true") +
200 HelpExampleRpc("getrawtransaction", "\"mytxid\", true") +
201 HelpExampleCli("getrawtransaction",
202 "\"mytxid\" false \"myblockhash\"") +
203 HelpExampleCli("getrawtransaction",
204 "\"mytxid\" true \"myblockhash\"")},
205 [&](const RPCHelpMan &self, const Config &config,
206 const JSONRPCRequest &request) -> UniValue {
207 const NodeContext &node = EnsureAnyNodeContext(request.context);
209
210 bool in_active_chain = true;
211 TxId txid = TxId(ParseHashV(request.params[0], "parameter 1"));
212 const CBlockIndex *blockindex = nullptr;
213
214 const CChainParams &params = config.GetChainParams();
215 if (txid == params.GenesisBlock().hashMerkleRoot) {
216 // Special exception for the genesis block coinbase transaction
217 throw JSONRPCError(
219 "The genesis block coinbase is not considered an "
220 "ordinary transaction and cannot be retrieved");
221 }
222
223 // Accept either a bool (true) or a num (>=1) to indicate verbose
224 // output.
225 bool fVerbose = false;
226 if (!request.params[1].isNull()) {
227 fVerbose = request.params[1].isNum()
228 ? (request.params[1].getInt<int>() != 0)
229 : request.params[1].get_bool();
230 }
231
232 if (!request.params[2].isNull()) {
233 LOCK(cs_main);
234
235 BlockHash blockhash(
236 ParseHashV(request.params[2], "parameter 3"));
237 blockindex = chainman.m_blockman.LookupBlockIndex(blockhash);
238 if (!blockindex) {
240 "Block hash not found");
241 }
242 in_active_chain = chainman.ActiveChain().Contains(blockindex);
243 }
244
245 bool f_txindex_ready = false;
246 if (g_txindex && !blockindex) {
247 f_txindex_ready = g_txindex->BlockUntilSyncedToCurrentChain();
248 }
249
250 BlockHash hash_block;
251 const CTransactionRef tx =
252 GetTransaction(blockindex, node.mempool.get(), txid, hash_block,
253 chainman.m_blockman);
254 if (!tx) {
255 std::string errmsg;
256 if (blockindex) {
258 return !blockindex->nStatus.hasData())) {
260 "Block not available");
261 }
262 errmsg = "No such transaction found in the provided block";
263 } else if (!g_txindex) {
264 errmsg =
265 "No such mempool transaction. Use -txindex or provide "
266 "a block hash to enable blockchain transaction queries";
267 } else if (!f_txindex_ready) {
268 errmsg = "No such mempool transaction. Blockchain "
269 "transactions are still in the process of being "
270 "indexed";
271 } else {
272 errmsg = "No such mempool or blockchain transaction";
273 }
274 throw JSONRPCError(
276 errmsg + ". Use gettransaction for wallet transactions.");
277 }
278
279 if (!fVerbose) {
280 return EncodeHexTx(*tx);
281 }
282
283 UniValue result(UniValue::VOBJ);
284 if (blockindex) {
285 result.pushKV("in_active_chain", in_active_chain);
286 }
287 TxToJSON(*tx, hash_block, result, chainman.ActiveChainstate());
288 return result;
289 },
290 };
291}
292
294 return RPCHelpMan{
295 "createrawtransaction",
296 "Create a transaction spending the given inputs and creating new "
297 "outputs.\n"
298 "Outputs can be addresses or data.\n"
299 "Returns hex-encoded raw transaction.\n"
300 "Note that the transaction's inputs are not signed, and\n"
301 "it is not stored in the wallet or transmitted to the network.\n",
302 {
303 {
304 "inputs",
307 "The inputs",
308 {
309 {
310 "",
313 "",
314 {
315 {"txid", RPCArg::Type::STR_HEX,
316 RPCArg::Optional::NO, "The transaction id"},
318 "The output number"},
319 {"sequence", RPCArg::Type::NUM,
320 RPCArg::DefaultHint{"depends on the value of the "
321 "'locktime' argument"},
322 "The sequence number"},
323 },
324 },
325 },
326 },
327 {"outputs",
330 "The outputs (key-value pairs), where none of "
331 "the keys are duplicated.\n"
332 "That is, each address can only appear once and there can only "
333 "be one 'data' object.\n"
334 "For compatibility reasons, a dictionary, which holds the "
335 "key-value pairs directly, is also\n"
336 " accepted as second parameter.",
337 {
338 {
339 "",
342 "",
343 {
345 "A key-value pair. The key (string) is the "
346 "bitcoin address, the value (float or string) is "
347 "the amount in " +
349 },
350 },
351 {
352 "",
355 "",
356 {
358 "A key-value pair. The key must be \"data\", the "
359 "value is hex-encoded data"},
360 },
361 },
362 },
364 {"locktime", RPCArg::Type::NUM, RPCArg::Default{0},
365 "Raw locktime. Non-0 value also locktime-activates inputs"},
366 },
367 RPCResult{RPCResult::Type::STR_HEX, "transaction",
368 "hex string of the transaction"},
370 HelpExampleCli("createrawtransaction",
371 "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
372 "\" \"[{\\\"address\\\":10000.00}]\"") +
373 HelpExampleCli("createrawtransaction",
374 "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
375 "\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") +
376 HelpExampleRpc("createrawtransaction",
377 "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
378 "\", \"[{\\\"address\\\":10000.00}]\"") +
379 HelpExampleRpc("createrawtransaction",
380 "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
381 "\", \"[{\\\"data\\\":\\\"00010203\\\"}]\"")},
382 [&](const RPCHelpMan &self, const Config &config,
383 const JSONRPCRequest &request) -> UniValue {
384 CMutableTransaction rawTx =
385 ConstructTransaction(config.GetChainParams(), request.params[0],
386 request.params[1], request.params[2]);
387
388 return EncodeHexTx(CTransaction(rawTx));
389 },
390 };
391}
392
394 return RPCHelpMan{
395 "decoderawtransaction",
396 "Return a JSON object representing the serialized, hex-encoded "
397 "transaction.\n",
398 {
400 "The transaction hex string"},
401 },
402 RPCResult{
404 "",
405 "",
406 DecodeTxDoc(/*txid_field_doc=*/"The transaction id",
407 /*wallet=*/false),
408 },
409 RPCExamples{HelpExampleCli("decoderawtransaction", "\"hexstring\"") +
410 HelpExampleRpc("decoderawtransaction", "\"hexstring\"")},
411 [&](const RPCHelpMan &self, const Config &config,
412 const JSONRPCRequest &request) -> UniValue {
414
415 if (!DecodeHexTx(mtx, request.params[0].get_str())) {
417 "TX decode failed");
418 }
419
420 UniValue result(UniValue::VOBJ);
421 TxToUniv(CTransaction(std::move(mtx)), BlockHash(), result, false);
422
423 return result;
424 },
425 };
426}
427
429 return RPCHelpMan{
430 "decodescript",
431 "Decode a hex-encoded script.\n",
432 {
434 "the hex-encoded script"},
435 },
436 RPCResult{
438 "",
439 "",
440 {
441 {RPCResult::Type::STR, "asm", "Script public key"},
442 {RPCResult::Type::STR, "type",
443 "The output type (e.g. " + GetAllOutputTypes() + ")"},
444 {RPCResult::Type::NUM, "reqSigs", "The required signatures"},
446 "addresses",
447 "",
448 {
449 {RPCResult::Type::STR, "address", "bitcoin address"},
450 }},
451 {RPCResult::Type::STR, "p2sh",
452 "address of P2SH script wrapping this redeem script (not "
453 "returned if the script is already a P2SH)"},
454 }},
455 RPCExamples{HelpExampleCli("decodescript", "\"hexstring\"") +
456 HelpExampleRpc("decodescript", "\"hexstring\"")},
457 [&](const RPCHelpMan &self, const Config &config,
458 const JSONRPCRequest &request) -> UniValue {
460 CScript script;
461 if (request.params[0].get_str().size() > 0) {
462 std::vector<uint8_t> scriptData(
463 ParseHexV(request.params[0], "argument"));
464 script = CScript(scriptData.begin(), scriptData.end());
465 } else {
466 // Empty scripts are valid.
467 }
468
469 ScriptPubKeyToUniv(script, r, /* fIncludeHex */ false);
470
471 UniValue type;
472 type = r.find_value("type");
473
474 if (type.isStr() && type.get_str() != "scripthash") {
475 // P2SH cannot be wrapped in a P2SH. If this script is already a
476 // P2SH, don't return the address for a P2SH of the P2SH.
477 r.pushKV("p2sh", EncodeDestination(ScriptHash(script), config));
478 }
479
480 return r;
481 },
482 };
483}
484
486 return RPCHelpMan{
487 "combinerawtransaction",
488 "Combine multiple partially signed transactions into one "
489 "transaction.\n"
490 "The combined transaction may be another partially signed transaction "
491 "or a \n"
492 "fully signed transaction.",
493 {
494 {
495 "txs",
498 "The hex strings of partially signed "
499 "transactions",
500 {
501 {"hexstring", RPCArg::Type::STR_HEX,
503 "A hex-encoded raw transaction"},
504 },
505 },
506 },
508 "The hex-encoded raw transaction with signature(s)"},
509 RPCExamples{HelpExampleCli("combinerawtransaction",
510 R"('["myhex1", "myhex2", "myhex3"]')")},
511 [&](const RPCHelpMan &self, const Config &config,
512 const JSONRPCRequest &request) -> UniValue {
513 const UniValue &txs = request.params[0].get_array();
514 std::vector<CMutableTransaction> txVariants(txs.size());
515
516 for (unsigned int idx = 0; idx < txs.size(); idx++) {
517 if (!DecodeHexTx(txVariants[idx], txs[idx].get_str())) {
518 throw JSONRPCError(
520 strprintf("TX decode failed for tx %d", idx));
521 }
522 }
523
524 if (txVariants.empty()) {
526 "Missing transactions");
527 }
528
529 // mergedTx will end up with all the signatures; it
530 // starts as a clone of the rawtx:
531 CMutableTransaction mergedTx(txVariants[0]);
532
533 // Fetch previous transactions (inputs):
534 CCoinsView viewDummy;
535 CCoinsViewCache view(&viewDummy);
536 {
537 NodeContext &node = EnsureAnyNodeContext(request.context);
538 const CTxMemPool &mempool = EnsureMemPool(node);
540 LOCK2(cs_main, mempool.cs);
541 CCoinsViewCache &viewChain =
542 chainman.ActiveChainstate().CoinsTip();
543 CCoinsViewMemPool viewMempool(&viewChain, mempool);
544 // temporarily switch cache backend to db+mempool view
545 view.SetBackend(viewMempool);
546
547 for (const CTxIn &txin : mergedTx.vin) {
548 // Load entries from viewChain into view; can fail.
549 view.AccessCoin(txin.prevout);
550 }
551
552 // switch back to avoid locking mempool for too long
553 view.SetBackend(viewDummy);
554 }
555
556 // Use CTransaction for the constant parts of the
557 // transaction to avoid rehashing.
558 const CTransaction txConst(mergedTx);
559 // Sign what we can:
560 for (size_t i = 0; i < mergedTx.vin.size(); i++) {
561 CTxIn &txin = mergedTx.vin[i];
562 const Coin &coin = view.AccessCoin(txin.prevout);
563 if (coin.IsSpent()) {
565 "Input not found or already spent");
566 }
567 SignatureData sigdata;
568
569 const CTxOut &txout = coin.GetTxOut();
570
571 // ... and merge in other signatures:
572 for (const CMutableTransaction &txv : txVariants) {
573 if (txv.vin.size() > i) {
574 sigdata.MergeSignatureData(
575 DataFromTransaction(txv, i, txout));
576 }
577 }
580 mergedTx, i, txout.nValue),
581 txout.scriptPubKey, sigdata);
582
583 UpdateInput(txin, sigdata);
584 }
585
586 return EncodeHexTx(CTransaction(mergedTx));
587 },
588 };
589}
590
592 return RPCHelpMan{
593 "signrawtransactionwithkey",
594 "Sign inputs for raw transaction (serialized, hex-encoded).\n"
595 "The second argument is an array of base58-encoded private\n"
596 "keys that will be the only keys used to sign the transaction.\n"
597 "The third optional argument (may be null) is an array of previous "
598 "transaction outputs that\n"
599 "this transaction depends on but may not yet be in the block chain.\n",
600 {
602 "The transaction hex string"},
603 {
604 "privkeys",
607 "The base58-encoded private keys for signing",
608 {
610 "private key in base58-encoding"},
611 },
612 },
613 {
614 "prevtxs",
617 "The previous dependent transaction outputs",
618 {
619 {
620 "",
623 "",
624 {
625 {"txid", RPCArg::Type::STR_HEX,
626 RPCArg::Optional::NO, "The transaction id"},
628 "The output number"},
629 {"scriptPubKey", RPCArg::Type::STR_HEX,
630 RPCArg::Optional::NO, "script key"},
631 {"redeemScript", RPCArg::Type::STR_HEX,
633 "(required for P2SH) redeem script"},
634 {"amount", RPCArg::Type::AMOUNT,
635 RPCArg::Optional::NO, "The amount spent"},
636 },
637 },
638 },
639 },
640 {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"ALL|FORKID"},
641 "The signature hash type. Must be one of:\n"
642 " \"ALL|FORKID\"\n"
643 " \"NONE|FORKID\"\n"
644 " \"SINGLE|FORKID\"\n"
645 " \"ALL|FORKID|ANYONECANPAY\"\n"
646 " \"NONE|FORKID|ANYONECANPAY\"\n"
647 " \"SINGLE|FORKID|ANYONECANPAY\""},
648 },
649 RPCResult{
651 "",
652 "",
653 {
655 "The hex-encoded raw transaction with signature(s)"},
656 {RPCResult::Type::BOOL, "complete",
657 "If the transaction has a complete set of signatures"},
659 "errors",
660 /* optional */ true,
661 "Script verification errors (if there are any)",
662 {
664 "",
665 "",
666 {
668 "The hash of the referenced, previous transaction"},
669 {RPCResult::Type::NUM, "vout",
670 "The index of the output to spent and used as "
671 "input"},
672 {RPCResult::Type::STR_HEX, "scriptSig",
673 "The hex-encoded signature script"},
674 {RPCResult::Type::NUM, "sequence",
675 "Script sequence number"},
676 {RPCResult::Type::STR, "error",
677 "Verification or signing error related to the "
678 "input"},
679 }},
680 }},
681 }},
683 HelpExampleCli("signrawtransactionwithkey",
684 "\"myhex\" \"[\\\"key1\\\",\\\"key2\\\"]\"") +
685 HelpExampleRpc("signrawtransactionwithkey",
686 "\"myhex\", \"[\\\"key1\\\",\\\"key2\\\"]\"")},
687 [&](const RPCHelpMan &self, const Config &config,
688 const JSONRPCRequest &request) -> UniValue {
690 if (!DecodeHexTx(mtx, request.params[0].get_str())) {
692 "TX decode failed");
693 }
694
696 const UniValue &keys = request.params[1].get_array();
697 for (size_t idx = 0; idx < keys.size(); ++idx) {
698 const UniValue &k = keys[idx];
699 CKey key = DecodeSecret(k.get_str());
700 if (!key.IsValid()) {
702 "Invalid private key");
703 }
704 keystore.AddKey(key);
705 }
706
707 // Fetch previous transactions (inputs):
708 std::map<COutPoint, Coin> coins;
709 for (const CTxIn &txin : mtx.vin) {
710 // Create empty map entry keyed by prevout.
711 coins[txin.prevout];
712 }
713 NodeContext &node = EnsureAnyNodeContext(request.context);
714 FindCoins(node, coins);
715
716 // Parse the prevtxs array
717 ParsePrevouts(request.params[2], &keystore, coins);
718
719 UniValue result(UniValue::VOBJ);
720 SignTransaction(mtx, &keystore, coins, request.params[3], result);
721 return result;
722 },
723 };
724}
725
727 return RPCHelpMan{
728 "decodepsbt",
729 "Return a JSON object representing the serialized, base64-encoded "
730 "partially signed Bitcoin transaction.\n",
731 {
733 "The PSBT base64 string"},
734 },
735 RPCResult{
737 "",
738 "",
739 {
741 "tx",
742 "The decoded network-serialized unsigned transaction.",
743 {
745 "The layout is the same as the output of "
746 "decoderawtransaction."},
747 }},
749 "unknown",
750 "The unknown global fields",
751 {
753 "(key-value pair) An unknown key-value pair"},
754 }},
756 "inputs",
757 "",
758 {
760 "",
761 "",
762 {
764 "utxo",
765 /* optional */ true,
766 "Transaction output for UTXOs",
767 {
768 {RPCResult::Type::NUM, "amount",
769 "The value in " + Currency::getTicker()},
771 "scriptPubKey",
772 "",
773 {
774 {RPCResult::Type::STR, "asm", "The asm"},
776 "The hex"},
777 {RPCResult::Type::STR, "type",
778 "The type, eg 'pubkeyhash'"},
779 {RPCResult::Type::STR, "address",
780 " Bitcoin address if there is one"},
781 }},
782 }},
784 "partial_signatures",
785 /* optional */ true,
786 "",
787 {
788 {RPCResult::Type::STR, "pubkey",
789 "The public key and signature that corresponds "
790 "to it."},
791 }},
792 {RPCResult::Type::STR, "sighash", /* optional */ true,
793 "The sighash type to be used"},
795 "redeem_script",
796 /* optional */ true,
797 "",
798 {
799 {RPCResult::Type::STR, "asm", "The asm"},
800 {RPCResult::Type::STR_HEX, "hex", "The hex"},
801 {RPCResult::Type::STR, "type",
802 "The type, eg 'pubkeyhash'"},
803 }},
805 "bip32_derivs",
806 /* optional */ true,
807 "",
808 {
810 "pubkey",
811 /* optional */ true,
812 "The public key with the derivation path as "
813 "the value.",
814 {
815 {RPCResult::Type::STR, "master_fingerprint",
816 "The fingerprint of the master key"},
817 {RPCResult::Type::STR, "path", "The path"},
818 }},
819 }},
821 "final_scriptsig",
822 /* optional */ true,
823 "",
824 {
825 {RPCResult::Type::STR, "asm", "The asm"},
826 {RPCResult::Type::STR, "hex", "The hex"},
827 }},
829 "unknown",
830 "The unknown global fields",
831 {
833 "(key-value pair) An unknown key-value pair"},
834 }},
835 }},
836 }},
838 "outputs",
839 "",
840 {
842 "",
843 "",
844 {
846 "redeem_script",
847 /* optional */ true,
848 "",
849 {
850 {RPCResult::Type::STR, "asm", "The asm"},
851 {RPCResult::Type::STR_HEX, "hex", "The hex"},
852 {RPCResult::Type::STR, "type",
853 "The type, eg 'pubkeyhash'"},
854 }},
856 "bip32_derivs",
857 /* optional */ true,
858 "",
859 {
861 "",
862 "",
863 {
864 {RPCResult::Type::STR, "pubkey",
865 "The public key this path corresponds to"},
866 {RPCResult::Type::STR, "master_fingerprint",
867 "The fingerprint of the master key"},
868 {RPCResult::Type::STR, "path", "The path"},
869 }},
870 }},
872 "unknown",
873 "The unknown global fields",
874 {
876 "(key-value pair) An unknown key-value pair"},
877 }},
878 }},
879 }},
880 {RPCResult::Type::STR_AMOUNT, "fee", /* optional */ true,
881 "The transaction fee paid if all UTXOs slots in the PSBT have "
882 "been filled."},
883 }},
884 RPCExamples{HelpExampleCli("decodepsbt", "\"psbt\"")},
885 [&](const RPCHelpMan &self, const Config &config,
886 const JSONRPCRequest &request) -> UniValue {
887 // Unserialize the transactions
889 std::string error;
890 if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
892 strprintf("TX decode failed %s", error));
893 }
894
895 UniValue result(UniValue::VOBJ);
896
897 // Add the decoded tx
898 UniValue tx_univ(UniValue::VOBJ);
899 TxToUniv(CTransaction(*psbtx.tx), BlockHash(), tx_univ, false);
900 result.pushKV("tx", std::move(tx_univ));
901
902 // Unknown data
903 if (psbtx.unknown.size() > 0) {
904 UniValue unknowns(UniValue::VOBJ);
905 for (auto entry : psbtx.unknown) {
906 unknowns.pushKV(HexStr(entry.first), HexStr(entry.second));
907 }
908 result.pushKV("unknown", std::move(unknowns));
909 }
910
911 // inputs
912 Amount total_in = Amount::zero();
913 bool have_all_utxos = true;
914 UniValue inputs(UniValue::VARR);
915 for (size_t i = 0; i < psbtx.inputs.size(); ++i) {
916 const PSBTInput &input = psbtx.inputs[i];
918 // UTXOs
919 if (!input.utxo.IsNull()) {
920 const CTxOut &txout = input.utxo;
921
923
924 out.pushKV("amount", txout.nValue);
925 if (MoneyRange(txout.nValue) &&
926 MoneyRange(total_in + txout.nValue)) {
927 total_in += txout.nValue;
928 } else {
929 // Hack to just not show fee later
930 have_all_utxos = false;
931 }
932
934 ScriptToUniv(txout.scriptPubKey, o, true);
935 out.pushKV("scriptPubKey", std::move(o));
936 in.pushKV("utxo", std::move(out));
937 } else {
938 have_all_utxos = false;
939 }
940
941 // Partial sigs
942 if (!input.partial_sigs.empty()) {
943 UniValue partial_sigs(UniValue::VOBJ);
944 for (const auto &sig : input.partial_sigs) {
945 partial_sigs.pushKV(HexStr(sig.second.first),
946 HexStr(sig.second.second));
947 }
948 in.pushKV("partial_signatures", std::move(partial_sigs));
949 }
950
951 // Sighash
952 if (input.sighash_type != std::nullopt) {
953 uint8_t sighashbyte =
954 input.sighash_type->getRawSigHashType() & 0xff;
955 in.pushKV("sighash", SighashToStr(sighashbyte));
956 }
957
958 // Redeem script
959 if (!input.redeem_script.empty()) {
961 ScriptToUniv(input.redeem_script, r, false);
962 in.pushKV("redeem_script", std::move(r));
963 }
964
965 // keypaths
966 if (!input.hd_keypaths.empty()) {
967 UniValue keypaths(UniValue::VARR);
968 for (auto entry : input.hd_keypaths) {
969 UniValue keypath(UniValue::VOBJ);
970 keypath.pushKV("pubkey", HexStr(entry.first));
971
972 keypath.pushKV(
973 "master_fingerprint",
974 strprintf("%08x",
975 ReadBE32(entry.second.fingerprint)));
976 keypath.pushKV("path",
977 WriteHDKeypath(entry.second.path));
978 keypaths.push_back(std::move(keypath));
979 }
980 in.pushKV("bip32_derivs", std::move(keypaths));
981 }
982
983 // Final scriptSig
984 if (!input.final_script_sig.empty()) {
985 UniValue scriptsig(UniValue::VOBJ);
986 scriptsig.pushKV(
987 "asm", ScriptToAsmStr(input.final_script_sig, true));
988 scriptsig.pushKV("hex", HexStr(input.final_script_sig));
989 in.pushKV("final_scriptSig", std::move(scriptsig));
990 }
991
992 // Unknown data
993 if (input.unknown.size() > 0) {
994 UniValue unknowns(UniValue::VOBJ);
995 for (auto entry : input.unknown) {
996 unknowns.pushKV(HexStr(entry.first),
997 HexStr(entry.second));
998 }
999 in.pushKV("unknown", std::move(unknowns));
1000 }
1001
1002 inputs.push_back(std::move(in));
1003 }
1004 result.pushKV("inputs", std::move(inputs));
1005
1006 // outputs
1007 Amount output_value = Amount::zero();
1008 UniValue outputs(UniValue::VARR);
1009 for (size_t i = 0; i < psbtx.outputs.size(); ++i) {
1010 const PSBTOutput &output = psbtx.outputs[i];
1012 // Redeem script
1013 if (!output.redeem_script.empty()) {
1015 ScriptToUniv(output.redeem_script, r, false);
1016 out.pushKV("redeem_script", std::move(r));
1017 }
1018
1019 // keypaths
1020 if (!output.hd_keypaths.empty()) {
1021 UniValue keypaths(UniValue::VARR);
1022 for (auto entry : output.hd_keypaths) {
1023 UniValue keypath(UniValue::VOBJ);
1024 keypath.pushKV("pubkey", HexStr(entry.first));
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(std::move(keypath));
1032 }
1033 out.pushKV("bip32_derivs", std::move(keypaths));
1034 }
1035
1036 // Unknown data
1037 if (output.unknown.size() > 0) {
1038 UniValue unknowns(UniValue::VOBJ);
1039 for (auto entry : output.unknown) {
1040 unknowns.pushKV(HexStr(entry.first),
1041 HexStr(entry.second));
1042 }
1043 out.pushKV("unknown", std::move(unknowns));
1044 }
1045
1046 outputs.push_back(std::move(out));
1047
1048 // Fee calculation
1049 if (MoneyRange(psbtx.tx->vout[i].nValue) &&
1050 MoneyRange(output_value + psbtx.tx->vout[i].nValue)) {
1051 output_value += psbtx.tx->vout[i].nValue;
1052 } else {
1053 // Hack to just not show fee later
1054 have_all_utxos = false;
1055 }
1056 }
1057 result.pushKV("outputs", std::move(outputs));
1058 if (have_all_utxos) {
1059 result.pushKV("fee", total_in - output_value);
1060 }
1061
1062 return result;
1063 },
1064 };
1065}
1066
1068 return RPCHelpMan{
1069 "combinepsbt",
1070 "Combine multiple partially signed Bitcoin transactions into one "
1071 "transaction.\n"
1072 "Implements the Combiner role.\n",
1073 {
1074 {
1075 "txs",
1078 "The base64 strings of partially signed transactions",
1079 {
1081 "A base64 string of a PSBT"},
1082 },
1083 },
1084 },
1086 "The base64-encoded partially signed transaction"},
1088 "combinepsbt", R"('["mybase64_1", "mybase64_2", "mybase64_3"]')")},
1089 [&](const RPCHelpMan &self, const Config &config,
1090 const JSONRPCRequest &request) -> UniValue {
1091 // Unserialize the transactions
1092 std::vector<PartiallySignedTransaction> psbtxs;
1093 const UniValue &txs = request.params[0].get_array();
1094 if (txs.empty()) {
1096 "Parameter 'txs' cannot be empty");
1097 }
1098 for (size_t i = 0; i < txs.size(); ++i) {
1100 std::string error;
1101 if (!DecodeBase64PSBT(psbtx, txs[i].get_str(), error)) {
1103 strprintf("TX decode failed %s", error));
1104 }
1105 psbtxs.push_back(psbtx);
1106 }
1107
1108 PartiallySignedTransaction merged_psbt;
1109 if (!CombinePSBTs(merged_psbt, psbtxs)) {
1110 throw JSONRPCError(
1112 "PSBTs not compatible (different transactions)");
1113 }
1114
1115 DataStream ssTx{};
1116 ssTx << merged_psbt;
1117 return EncodeBase64(ssTx);
1118 },
1119 };
1120}
1121
1123 return RPCHelpMan{
1124 "finalizepsbt",
1125 "Finalize the inputs of a PSBT. If the transaction is fully signed, it "
1126 "will produce a\n"
1127 "network serialized transaction which can be broadcast with "
1128 "sendrawtransaction. Otherwise a PSBT will be\n"
1129 "created which has the final_scriptSigfields filled for inputs that "
1130 "are complete.\n"
1131 "Implements the Finalizer and Extractor roles.\n",
1132 {
1134 "A base64 string of a PSBT"},
1135 {"extract", RPCArg::Type::BOOL, RPCArg::Default{true},
1136 "If true and the transaction is complete,\n"
1137 " extract and return the complete "
1138 "transaction in normal network serialization instead of the "
1139 "PSBT."},
1140 },
1142 "",
1143 "",
1144 {
1145 {RPCResult::Type::STR, "psbt",
1146 "The base64-encoded partially signed transaction if not "
1147 "extracted"},
1149 "The hex-encoded network transaction if extracted"},
1150 {RPCResult::Type::BOOL, "complete",
1151 "If the transaction has a complete set of signatures"},
1152 }},
1153 RPCExamples{HelpExampleCli("finalizepsbt", "\"psbt\"")},
1154 [&](const RPCHelpMan &self, const Config &config,
1155 const JSONRPCRequest &request) -> UniValue {
1156 // Unserialize the transactions
1158 std::string error;
1159 if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
1161 strprintf("TX decode failed %s", error));
1162 }
1163
1164 bool extract =
1165 request.params[1].isNull() ||
1166 (!request.params[1].isNull() && request.params[1].get_bool());
1167
1169 bool complete = FinalizeAndExtractPSBT(psbtx, mtx);
1170
1171 UniValue result(UniValue::VOBJ);
1172 DataStream ssTx{};
1173 std::string result_str;
1174
1175 if (complete && extract) {
1176 ssTx << mtx;
1177 result_str = HexStr(ssTx);
1178 result.pushKV("hex", result_str);
1179 } else {
1180 ssTx << psbtx;
1181 result_str = EncodeBase64(ssTx.str());
1182 result.pushKV("psbt", result_str);
1183 }
1184 result.pushKV("complete", complete);
1185
1186 return result;
1187 },
1188 };
1189}
1190
1192 return RPCHelpMan{
1193 "createpsbt",
1194 "Creates a transaction in the Partially Signed Transaction format.\n"
1195 "Implements the Creator role.\n",
1196 {
1197 {
1198 "inputs",
1201 "The json objects",
1202 {
1203 {
1204 "",
1207 "",
1208 {
1209 {"txid", RPCArg::Type::STR_HEX,
1210 RPCArg::Optional::NO, "The transaction id"},
1212 "The output number"},
1213 {"sequence", RPCArg::Type::NUM,
1214 RPCArg::DefaultHint{"depends on the value of the "
1215 "'locktime' argument"},
1216 "The sequence number"},
1217 },
1218 },
1219 },
1220 },
1221 {"outputs",
1224 "The outputs (key-value pairs), where none of "
1225 "the keys are duplicated.\n"
1226 "That is, each address can only appear once and there can only "
1227 "be one 'data' object.\n"
1228 "For compatibility reasons, a dictionary, which holds the "
1229 "key-value pairs directly, is also\n"
1230 " accepted as second parameter.",
1231 {
1232 {
1233 "",
1236 "",
1237 {
1239 "A key-value pair. The key (string) is the "
1240 "bitcoin address, the value (float or string) is "
1241 "the amount in " +
1243 },
1244 },
1245 {
1246 "",
1249 "",
1250 {
1252 "A key-value pair. The key must be \"data\", the "
1253 "value is hex-encoded data"},
1254 },
1255 },
1256 },
1258 {"locktime", RPCArg::Type::NUM, RPCArg::Default{0},
1259 "Raw locktime. Non-0 value also locktime-activates inputs"},
1260 },
1262 "The resulting raw transaction (base64-encoded string)"},
1264 "createpsbt", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
1265 "\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"")},
1266 [&](const RPCHelpMan &self, const Config &config,
1267 const JSONRPCRequest &request) -> UniValue {
1268 CMutableTransaction rawTx =
1269 ConstructTransaction(config.GetChainParams(), request.params[0],
1270 request.params[1], request.params[2]);
1271
1272 // Make a blank psbt
1274 psbtx.tx = rawTx;
1275 for (size_t i = 0; i < rawTx.vin.size(); ++i) {
1276 psbtx.inputs.push_back(PSBTInput());
1277 }
1278 for (size_t i = 0; i < rawTx.vout.size(); ++i) {
1279 psbtx.outputs.push_back(PSBTOutput());
1280 }
1281
1282 // Serialize the PSBT
1283 DataStream ssTx{};
1284 ssTx << psbtx;
1285
1286 return EncodeBase64(ssTx);
1287 },
1288 };
1289}
1290
1292 return RPCHelpMan{
1293 "converttopsbt",
1294 "Converts a network serialized transaction to a PSBT. "
1295 "This should be used only with createrawtransaction and "
1296 "fundrawtransaction\n"
1297 "createpsbt and walletcreatefundedpsbt should be used for new "
1298 "applications.\n",
1299 {
1301 "The hex string of a raw transaction"},
1302 {"permitsigdata", RPCArg::Type::BOOL, RPCArg::Default{false},
1303 "If true, any signatures in the input will be discarded and "
1304 "conversion.\n"
1305 " will continue. If false, RPC will "
1306 "fail if any signatures are present."},
1307 },
1309 "The resulting raw transaction (base64-encoded string)"},
1311 "\nCreate a transaction\n" +
1312 HelpExampleCli("createrawtransaction",
1313 "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
1314 "\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") +
1315 "\nConvert the transaction to a PSBT\n" +
1316 HelpExampleCli("converttopsbt", "\"rawtransaction\"")},
1317 [&](const RPCHelpMan &self, const Config &config,
1318 const JSONRPCRequest &request) -> UniValue {
1319 // parse hex string from parameter
1321 bool permitsigdata = request.params[1].isNull()
1322 ? false
1323 : request.params[1].get_bool();
1324 if (!DecodeHexTx(tx, request.params[0].get_str())) {
1326 "TX decode failed");
1327 }
1328
1329 // Remove all scriptSigs from inputs
1330 for (CTxIn &input : tx.vin) {
1331 if (!input.scriptSig.empty() && !permitsigdata) {
1333 "Inputs must not have scriptSigs");
1334 }
1335 input.scriptSig.clear();
1336 }
1337
1338 // Make a blank psbt
1340 psbtx.tx = tx;
1341 for (size_t i = 0; i < tx.vin.size(); ++i) {
1342 psbtx.inputs.push_back(PSBTInput());
1343 }
1344 for (size_t i = 0; i < tx.vout.size(); ++i) {
1345 psbtx.outputs.push_back(PSBTOutput());
1346 }
1347
1348 // Serialize the PSBT
1349 DataStream ssTx{};
1350 ssTx << psbtx;
1351
1352 return EncodeBase64(ssTx);
1353 },
1354 };
1355}
1356
1358 return RPCHelpMan{
1359 "utxoupdatepsbt",
1360 "Updates all inputs and outputs in a PSBT with data from output "
1361 "descriptors, the UTXO set or the mempool.\n",
1362 {
1364 "A base64 string of a PSBT"},
1365 {"descriptors",
1368 "An array of either strings or objects",
1369 {
1371 "An output descriptor"},
1372 {"",
1375 "An object with an output descriptor and extra information",
1376 {
1378 "An output descriptor"},
1379 {"range", RPCArg::Type::RANGE, RPCArg::Default{1000},
1380 "Up to what index HD chains should be explored (either "
1381 "end or [begin,end])"},
1382 }},
1383 }},
1384 },
1386 "The base64-encoded partially signed transaction with inputs "
1387 "updated"},
1388 RPCExamples{HelpExampleCli("utxoupdatepsbt", "\"psbt\"")},
1389 [&](const RPCHelpMan &self, const Config &config,
1390 const JSONRPCRequest &request) -> UniValue {
1391 // Parse descriptors, if any.
1392 FlatSigningProvider provider;
1393 if (!request.params[1].isNull()) {
1394 auto descs = request.params[1].get_array();
1395 for (size_t i = 0; i < descs.size(); ++i) {
1396 EvalDescriptorStringOrObject(descs[i], provider);
1397 }
1398 }
1399 // We don't actually need private keys further on; hide them as a
1400 // precaution.
1402 request.params[0].get_str(), request.context,
1403 HidingSigningProvider(&provider, /*hide_secret=*/true,
1404 /*hide_origin=*/false));
1405
1406 DataStream ssTx{};
1407 ssTx << psbtx;
1408 return EncodeBase64(ssTx);
1409 },
1410 };
1411}
1412
1414 return RPCHelpMan{
1415 "joinpsbts",
1416 "Joins multiple distinct PSBTs with different inputs and outputs "
1417 "into one PSBT with inputs and outputs from all of the PSBTs\n"
1418 "No input in any of the PSBTs can be in more than one of the PSBTs.\n",
1419 {{"txs",
1422 "The base64 strings of partially signed transactions",
1424 "A base64 string of a PSBT"}}}},
1426 "The base64-encoded partially signed transaction"},
1427 RPCExamples{HelpExampleCli("joinpsbts", "\"psbt\"")},
1428 [&](const RPCHelpMan &self, const Config &config,
1429 const JSONRPCRequest &request) -> UniValue {
1430 // Unserialize the transactions
1431 std::vector<PartiallySignedTransaction> psbtxs;
1432 const UniValue &txs = request.params[0].get_array();
1433
1434 if (txs.size() <= 1) {
1435 throw JSONRPCError(
1437 "At least two PSBTs are required to join PSBTs.");
1438 }
1439
1440 uint32_t best_version = 1;
1441 uint32_t best_locktime = 0xffffffff;
1442 for (size_t i = 0; i < txs.size(); ++i) {
1444 std::string error;
1445 if (!DecodeBase64PSBT(psbtx, txs[i].get_str(), error)) {
1447 strprintf("TX decode failed %s", error));
1448 }
1449 psbtxs.push_back(psbtx);
1450 // Choose the highest version number
1451 if (psbtx.tx->nVersion > best_version) {
1452 best_version = psbtx.tx->nVersion;
1453 }
1454 // Choose the lowest lock time
1455 if (psbtx.tx->nLockTime < best_locktime) {
1456 best_locktime = psbtx.tx->nLockTime;
1457 }
1458 }
1459
1460 // Create a blank psbt where everything will be added
1461 PartiallySignedTransaction merged_psbt;
1462 merged_psbt.tx = CMutableTransaction();
1463 merged_psbt.tx->nVersion = best_version;
1464 merged_psbt.tx->nLockTime = best_locktime;
1465
1466 // Merge
1467 for (auto &psbt : psbtxs) {
1468 for (size_t i = 0; i < psbt.tx->vin.size(); ++i) {
1469 if (!merged_psbt.AddInput(psbt.tx->vin[i],
1470 psbt.inputs[i])) {
1471 throw JSONRPCError(
1473 strprintf("Input %s:%d exists in multiple PSBTs",
1474 psbt.tx->vin[i]
1475 .prevout.GetTxId()
1476 .ToString()
1477 .c_str(),
1478 psbt.tx->vin[i].prevout.GetN()));
1479 }
1480 }
1481 for (size_t i = 0; i < psbt.tx->vout.size(); ++i) {
1482 merged_psbt.AddOutput(psbt.tx->vout[i], psbt.outputs[i]);
1483 }
1484 merged_psbt.unknown.insert(psbt.unknown.begin(),
1485 psbt.unknown.end());
1486 }
1487
1488 // Generate list of shuffled indices for shuffling inputs and
1489 // outputs of the merged PSBT
1490 std::vector<int> input_indices(merged_psbt.inputs.size());
1491 std::iota(input_indices.begin(), input_indices.end(), 0);
1492 std::vector<int> output_indices(merged_psbt.outputs.size());
1493 std::iota(output_indices.begin(), output_indices.end(), 0);
1494
1495 // Shuffle input and output indices lists
1496 Shuffle(input_indices.begin(), input_indices.end(),
1498 Shuffle(output_indices.begin(), output_indices.end(),
1500
1501 PartiallySignedTransaction shuffled_psbt;
1502 shuffled_psbt.tx = CMutableTransaction();
1503 shuffled_psbt.tx->nVersion = merged_psbt.tx->nVersion;
1504 shuffled_psbt.tx->nLockTime = merged_psbt.tx->nLockTime;
1505 for (int i : input_indices) {
1506 shuffled_psbt.AddInput(merged_psbt.tx->vin[i],
1507 merged_psbt.inputs[i]);
1508 }
1509 for (int i : output_indices) {
1510 shuffled_psbt.AddOutput(merged_psbt.tx->vout[i],
1511 merged_psbt.outputs[i]);
1512 }
1513 shuffled_psbt.unknown.insert(merged_psbt.unknown.begin(),
1514 merged_psbt.unknown.end());
1515
1516 DataStream ssTx{};
1517 ssTx << shuffled_psbt;
1518 return EncodeBase64(ssTx);
1519 },
1520 };
1521}
1522
1524 return RPCHelpMan{
1525 "analyzepsbt",
1526 "Analyzes and provides information about the current status of a "
1527 "PSBT and its inputs\n",
1529 "A base64 string of a PSBT"}},
1530 RPCResult{
1532 "",
1533 "",
1534 {
1536 "inputs",
1537 "",
1538 {
1540 "",
1541 "",
1542 {
1543 {RPCResult::Type::BOOL, "has_utxo",
1544 "Whether a UTXO is provided"},
1545 {RPCResult::Type::BOOL, "is_final",
1546 "Whether the input is finalized"},
1548 "missing",
1549 /* optional */ true,
1550 "Things that are missing that are required to "
1551 "complete this input",
1552 {
1554 "pubkeys",
1555 /* optional */ true,
1556 "",
1557 {
1558 {RPCResult::Type::STR_HEX, "keyid",
1559 "Public key ID, hash160 of the public "
1560 "key, of a public key whose BIP 32 "
1561 "derivation path is missing"},
1562 }},
1564 "signatures",
1565 /* optional */ true,
1566 "",
1567 {
1568 {RPCResult::Type::STR_HEX, "keyid",
1569 "Public key ID, hash160 of the public "
1570 "key, of a public key whose signature is "
1571 "missing"},
1572 }},
1573 {RPCResult::Type::STR_HEX, "redeemscript",
1574 /* optional */ true,
1575 "Hash160 of the redeemScript that is missing"},
1576 }},
1577 {RPCResult::Type::STR, "next", /* optional */ true,
1578 "Role of the next person that this input needs to "
1579 "go to"},
1580 }},
1581 }},
1582 {RPCResult::Type::NUM, "estimated_vsize", /* optional */ true,
1583 "Estimated vsize of the final signed transaction"},
1584 {RPCResult::Type::STR_AMOUNT, "estimated_feerate",
1585 /* optional */ true,
1586 "Estimated feerate of the final signed transaction in " +
1588 "/kB. Shown only if all UTXO slots in the PSBT have been "
1589 "filled"},
1590 {RPCResult::Type::STR_AMOUNT, "fee", /* optional */ true,
1591 "The transaction fee paid. Shown only if all UTXO slots in "
1592 "the PSBT have been filled"},
1593 {RPCResult::Type::STR, "next",
1594 "Role of the next person that this psbt needs to go to"},
1595 {RPCResult::Type::STR, "error", /* optional */ true,
1596 "Error message (if there is one)"},
1597 }},
1598 RPCExamples{HelpExampleCli("analyzepsbt", "\"psbt\"")},
1599 [&](const RPCHelpMan &self, const Config &config,
1600 const JSONRPCRequest &request) -> UniValue {
1601 // Unserialize the transaction
1603 std::string error;
1604 if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
1606 strprintf("TX decode failed %s", error));
1607 }
1608
1609 PSBTAnalysis psbta = AnalyzePSBT(psbtx);
1610
1611 UniValue result(UniValue::VOBJ);
1612 UniValue inputs_result(UniValue::VARR);
1613 for (const auto &input : psbta.inputs) {
1614 UniValue input_univ(UniValue::VOBJ);
1615 UniValue missing(UniValue::VOBJ);
1616
1617 input_univ.pushKV("has_utxo", input.has_utxo);
1618 input_univ.pushKV("is_final", input.is_final);
1619 input_univ.pushKV("next", PSBTRoleName(input.next));
1620
1621 if (!input.missing_pubkeys.empty()) {
1622 UniValue missing_pubkeys_univ(UniValue::VARR);
1623 for (const CKeyID &pubkey : input.missing_pubkeys) {
1624 missing_pubkeys_univ.push_back(HexStr(pubkey));
1625 }
1626 missing.pushKV("pubkeys", std::move(missing_pubkeys_univ));
1627 }
1628 if (!input.missing_redeem_script.IsNull()) {
1629 missing.pushKV("redeemscript",
1630 HexStr(input.missing_redeem_script));
1631 }
1632 if (!input.missing_sigs.empty()) {
1633 UniValue missing_sigs_univ(UniValue::VARR);
1634 for (const CKeyID &pubkey : input.missing_sigs) {
1635 missing_sigs_univ.push_back(HexStr(pubkey));
1636 }
1637 missing.pushKV("signatures", std::move(missing_sigs_univ));
1638 }
1639 if (!missing.getKeys().empty()) {
1640 input_univ.pushKV("missing", std::move(missing));
1641 }
1642 inputs_result.push_back(std::move(input_univ));
1643 }
1644 if (!inputs_result.empty()) {
1645 result.pushKV("inputs", std::move(inputs_result));
1646 }
1647 if (psbta.estimated_vsize != std::nullopt) {
1648 result.pushKV("estimated_vsize", (int)*psbta.estimated_vsize);
1649 }
1650 if (psbta.estimated_feerate != std::nullopt) {
1651 result.pushKV("estimated_feerate",
1652 psbta.estimated_feerate->GetFeePerK());
1653 }
1654 if (psbta.fee != std::nullopt) {
1655 result.pushKV("fee", *psbta.fee);
1656 }
1657 result.pushKV("next", PSBTRoleName(psbta.next));
1658 if (!psbta.error.empty()) {
1659 result.pushKV("error", psbta.error);
1660 }
1661
1662 return result;
1663 },
1664 };
1665}
1666
1668 return RPCHelpMan{
1669 "gettransactionstatus",
1670 "Return the current pool a transaction belongs to\n",
1671 {
1673 "The transaction id"},
1674 },
1675 RPCResult{
1677 "",
1678 "",
1679 {
1680 {RPCResult::Type::STR, "pool",
1681 "In which pool the transaction is currently located, "
1682 "either none, mempool, orphanage or conflicting"},
1683 {RPCResult::Type::STR, "block",
1684 "If the transaction is mined, this is the blockhash of the "
1685 "mining block, otherwise \"none\". This field is only "
1686 "present if -txindex is enabled."},
1687 }},
1688 RPCExamples{HelpExampleCli("gettransactionstatus", "\"txid\"")},
1689 [&](const RPCHelpMan &self, const Config &config,
1690 const JSONRPCRequest &request) -> UniValue {
1691 const NodeContext &node = EnsureAnyNodeContext(request.context);
1692 CTxMemPool &mempool = EnsureMemPool(node);
1693
1694 TxId txid = TxId(ParseHashV(request.params[0], "parameter 1"));
1695
1697
1698 if (mempool.exists(txid)) {
1699 ret.pushKV("pool", "mempool");
1700 } else if (mempool.withOrphanage(
1701 [&txid](const TxOrphanage &orphanage) {
1702 return orphanage.HaveTx(txid);
1703 })) {
1704 ret.pushKV("pool", "orphanage");
1705 } else if (mempool.withConflicting(
1706 [&txid](const TxConflicting &conflicting) {
1707 return conflicting.HaveTx(txid);
1708 })) {
1709 ret.pushKV("pool", "conflicting");
1710 } else {
1711 ret.pushKV("pool", "none");
1712 }
1713
1714 if (g_txindex) {
1715 if (!g_txindex->BlockUntilSyncedToCurrentChain()) {
1716 throw JSONRPCError(
1718 "Blockchain transactions are still in the process of "
1719 "being indexed");
1720 }
1721
1722 CTransactionRef tx;
1723 BlockHash blockhash;
1724 if (g_txindex->FindTx(txid, blockhash, tx)) {
1725 ret.pushKV("block", blockhash.GetHex());
1726 } else {
1727 ret.pushKV("block", "none");
1728 }
1729 }
1730
1731 return ret;
1732 },
1733 };
1734}
1735
1737 // clang-format off
1738 static const CRPCCommand commands[] = {
1739 // category actor (function)
1740 // ------------------ ----------------------
1741 { "rawtransactions", getrawtransaction, },
1742 { "rawtransactions", createrawtransaction, },
1743 { "rawtransactions", decoderawtransaction, },
1744 { "rawtransactions", decodescript, },
1745 { "rawtransactions", combinerawtransaction, },
1746 { "rawtransactions", signrawtransactionwithkey, },
1747 { "rawtransactions", decodepsbt, },
1748 { "rawtransactions", combinepsbt, },
1749 { "rawtransactions", finalizepsbt, },
1750 { "rawtransactions", createpsbt, },
1751 { "rawtransactions", converttopsbt, },
1752 { "rawtransactions", utxoupdatepsbt, },
1753 { "rawtransactions", joinpsbts, },
1754 { "rawtransactions", analyzepsbt, },
1755 { "rawtransactions", gettransactionstatus, },
1756 };
1757 // clang-format on
1758 for (const auto &c : commands) {
1759 t.appendCommand(c.name, &c);
1760 }
1761}
bool MoneyRange(const Amount nValue)
Definition: amount.h:177
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:159
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:190
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
Definition: chain.h:170
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:48
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:357
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
Definition: coins.cpp:199
Abstract view on the open txout dataset.
Definition: coins.h:303
CCoinsView that brings transactions from a mempool into view.
Definition: txmempool.h:643
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:330
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition: txmempool.h:222
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
Definition: txmempool.h:316
bool exists(const TxId &txid) const
Definition: txmempool.h:525
auto withOrphanage(Callable &&func) const EXCLUSIVE_LOCKS_REQUIRED(!cs_orphanage)
Definition: txmempool.h:586
auto withConflicting(Callable &&func) const EXCLUSIVE_LOCKS_REQUIRED(!cs_conflicting)
Definition: txmempool.h:594
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:727
CChain m_chain
The current chain of blockheaders we consult and build on.
Definition: validation.h:826
node::BlockManager & m_blockman
Reference to a BlockManager instance which itself is shared across all Chainstate instances.
Definition: validation.h:784
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
Definition: validation.h:1176
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:1446
CChain & ActiveChain() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
Definition: validation.h:1447
node::BlockManager m_blockman
A single BlockManager instance is shared across each constructed chainstate to avoid duplicating bloc...
Definition: validation.h:1336
A UTXO entry.
Definition: coins.h:31
CTxOut & GetTxOut()
Definition: coins.h:52
bool IsSpent() const
Definition: coins.h:50
Definition: config.h:19
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:118
Fast randomness source.
Definition: random.h:411
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:39
Signature hash type wrapper class.
Definition: sighashtype.h:37
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
constexpr bool IsNull() const
Definition: uint256.h:44
std::string GetHex() const
Definition: uint256.cpp:10
CBlockIndex * LookupBlockIndex(const BlockHash &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
void ScriptToUniv(const CScript &script, UniValue &out, bool include_address)
Definition: core_write.cpp:180
std::string EncodeHexTx(const CTransaction &tx)
Definition: core_write.cpp:174
std::string SighashToStr(uint8_t sighash_type)
Definition: core_write.cpp:90
void ScriptPubKeyToUniv(const CScript &scriptPubKey, UniValue &out, bool fIncludeHex)
Definition: core_write.cpp:195
bool DecodeHexTx(CMutableTransaction &tx, const std::string &strHexTx)
Definition: core_read.cpp:196
std::string ScriptToAsmStr(const CScript &script, const bool fAttemptSighashDecode=false)
Create the assembly string representation of a CScript object.
Definition: core_write.cpp:107
void TxToUniv(const CTransaction &tx, const BlockHash &hashBlock, UniValue &entry, bool include_hex=true, const CTxUndo *txundo=nullptr, TxVerbosity verbosity=TxVerbosity::SHOW_DETAILS, std::function< bool(const CTxOut &)> is_change_func={})
Definition: core_write.cpp:222
static uint32_t ReadBE32(const uint8_t *ptr)
Definition: common.h:52
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition: cs_main.cpp:7
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
Definition: hex_base.cpp:30
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: messages.h:12
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:538
bool DecodeBase64PSBT(PartiallySignedTransaction &psbt, const std::string &base64_tx, std::string &error)
Decode a base64ed PSBT into a PartiallySignedTransaction.
Definition: psbt.cpp:302
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:285
bool 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:271
bool SignPSBTInput(const SigningProvider &provider, PartiallySignedTransaction &psbt, int index, SigHashType sighash, SignatureData *out_sigdata, bool use_dummy, bool finalize)
Signs a PSBTInput, verifying that all provided data matches what is being signed.
Definition: psbt.cpp:186
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:255
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
Definition: random.h:512
RPCHelpMan joinpsbts()
static RPCHelpMan getrawtransaction()
static RPCHelpMan converttopsbt()
RPCHelpMan analyzepsbt()
static RPCHelpMan decoderawtransaction()
static RPCHelpMan combinepsbt()
PartiallySignedTransaction ProcessPSBT(const std::string &psbt_string, const std::any &context, const HidingSigningProvider &provider)
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.
std::vector< RPCResult > DecodeTxDoc(const std::string &txid_field_doc, bool wallet)
Explain the UniValue "decoded" transaction object, may include extra fields if processed by wallet.
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:164
std::vector< uint8_t > ParseHexV(const UniValue &v, std::string strName)
Definition: util.cpp:108
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:181
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:1383
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:36
std::string GetAllOutputTypes()
Definition: util.cpp:319
uint256 ParseHashV(const UniValue &v, std::string strName)
Utilities: convert hex-encoded values (throws error if not hex).
Definition: util.cpp:87
#define extract(n)
Extract the lowest 64 bits of (c0,c1,c2) into n, and left shift the number 64 bits.
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:210
void UpdateInput(CTxIn &input, const SignatureData &data)
Definition: sign.cpp:343
SignatureData DataFromTransaction(const CMutableTransaction &tx, unsigned int nIn, const CTxOut &txout)
Extract signature data from a transaction input, and insert it.
Definition: sign.cpp:287
const SigningProvider & DUMMY_SIGNING_PROVIDER
Definition: amount.h:23
static constexpr Amount zero() noexcept
Definition: amount.h:36
A BlockHash is a unqiue identifier for a block.
Definition: blockhash.h:13
static std::string getTicker()
Definition: amount.h:163
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
std::optional< 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:235
CScript redeem_script
Definition: psbt.h:236
std::map< CPubKey, KeyOriginInfo > hd_keypaths
Definition: psbt.h:237
std::map< std::vector< uint8_t >, std::vector< uint8_t > > unknown
Definition: psbt.h:238
A version of CTransaction with the PSBT format.
Definition: psbt.h:336
std::map< std::vector< uint8_t >, std::vector< uint8_t > > unknown
Definition: psbt.h:340
bool AddOutput(const CTxOut &txout, const PSBTOutput &psbtout)
Definition: psbt.cpp:50
std::vector< PSBTInput > inputs
Definition: psbt.h:338
std::optional< CMutableTransaction > tx
Definition: psbt.h:337
bool AddInput(const CTxIn &txin, PSBTInput &psbtin)
Definition: psbt.cpp:38
std::vector< PSBTOutput > outputs
Definition: psbt.h:339
@ 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:212
@ 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:146
@ 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:347
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:50
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:298
#define LOCK(cs)
Definition: sync.h:295
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:343
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1203
std::unique_ptr< TxIndex > g_txindex
The global transaction index, used in GetTransaction. May be null.
Definition: txindex.cpp:17
std::string EncodeBase64(Span< const uint8_t > input)