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