Bitcoin ABC 0.26.3
P2P Digital Currency
Loading...
Searching...
No Matches
rawtransaction.cpp
Go to the documentation of this file.
1// Copyright (c) 2010 Satoshi Nakamoto
2// Copyright (c) 2009-2016 The Bitcoin Core developers
3// Distributed under the MIT software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#include <chain.h>
7#include <chainparams.h>
8#include <coins.h>
9#include <config.h>
10#include <consensus/amount.h>
12#include <core_io.h>
13#include <index/txindex.h>
14#include <key_io.h>
15#include <node/blockstorage.h>
16#include <node/coin.h>
17#include <node/context.h>
18#include <node/psbt.h>
19#include <node/transaction.h>
20#include <policy/packages.h>
21#include <policy/policy.h>
23#include <psbt.h>
24#include <random.h>
25#include <rpc/blockchain.h>
27#include <rpc/server.h>
28#include <rpc/server_util.h>
29#include <rpc/util.h>
30#include <script/script.h>
31#include <script/sign.h>
33#include <script/standard.h>
34#include <txmempool.h>
35#include <uint256.h>
36#include <util/bip32.h>
37#include <util/check.h>
38#include <util/error.h>
39#include <util/strencodings.h>
40#include <util/string.h>
41#include <validation.h>
42#include <validationinterface.h>
43
44#include <cstdint>
45#include <numeric>
46
47#include <univalue.h>
48
51using node::FindCoins;
55
56static void TxToJSON(const CTransaction &tx, const BlockHash &hashBlock,
58 // Call into TxToUniv() in bitcoin-common to decode the transaction hex.
59 //
60 // Blockchain contextual information (confirmations and blocktime) is not
61 // available to code in bitcoin-common, so we query them here and push the
62 // data into the returned UniValue.
63 TxToUniv(tx, BlockHash(), entry, true, RPCSerializationFlags());
64
65 if (!hashBlock.IsNull()) {
67
68 entry.pushKV("blockhash", hashBlock.GetHex());
69 const CBlockIndex *pindex =
70 active_chainstate.m_blockman.LookupBlockIndex(hashBlock);
71 if (pindex) {
72 if (active_chainstate.m_chain.Contains(pindex)) {
73 entry.pushKV("confirmations",
74 1 + active_chainstate.m_chain.Height() -
75 pindex->nHeight);
76 entry.pushKV("time", pindex->GetBlockTime());
77 entry.pushKV("blocktime", pindex->GetBlockTime());
78 } else {
79 entry.pushKV("confirmations", 0);
80 }
81 }
82 }
83}
84
86 return RPCHelpMan{
87 "getrawtransaction",
88 "\nReturn the raw transaction data.\n"
89 "\nBy default, this call only returns a transaction if it is in the "
90 "mempool. If -txindex is enabled\n"
91 "and no blockhash argument is passed, it will return the transaction "
92 "if it is in the mempool or any block.\n"
93 "If a blockhash argument is passed, it will return the transaction if\n"
94 "the specified block is available and the transaction is in that "
95 "block.\n"
96 "\nIf verbose is 'true', returns an Object with information about "
97 "'txid'.\n"
98 "If verbose is 'false' or omitted, returns a string that is "
99 "serialized, hex-encoded data for 'txid'.\n",
100 {
102 "The transaction id"},
103 // Verbose is a boolean, but we accept an int for backward
104 // compatibility
105 {"verbose", RPCArg::Type::BOOL, RPCArg::Default{false},
106 "If false, return a string, otherwise return a json object",
108 {"blockhash", RPCArg::Type::STR_HEX,
110 "The block in which to look for the transaction"},
111 },
112 {
113 RPCResult{"if verbose is not set or set to false",
114 RPCResult::Type::STR, "data",
115 "The serialized, hex-encoded data for 'txid'"},
116 RPCResult{
117 "if verbose is set to true",
119 "",
120 "",
121 {
122 {RPCResult::Type::BOOL, "in_active_chain",
123 "Whether specified block is in the active chain or not "
124 "(only present with explicit \"blockhash\" argument)"},
126 "The serialized, hex-encoded data for 'txid'"},
128 "The transaction id (same as provided)"},
129 {RPCResult::Type::STR_HEX, "hash", "The transaction hash"},
130 {RPCResult::Type::NUM, "size",
131 "The serialized transaction size"},
132 {RPCResult::Type::NUM, "version", "The version"},
133 {RPCResult::Type::NUM_TIME, "locktime", "The lock time"},
135 "vin",
136 "",
137 {
139 "",
140 "",
141 {
143 "The transaction id"},
144 {RPCResult::Type::STR, "vout", ""},
146 "scriptSig",
147 "The script",
148 {
149 {RPCResult::Type::STR, "asm", "asm"},
150 {RPCResult::Type::STR_HEX, "hex", "hex"},
151 }},
152 {RPCResult::Type::NUM, "sequence",
153 "The script sequence number"},
154 }},
155 }},
157 "vout",
158 "",
159 {
161 "",
162 "",
163 {
164 {RPCResult::Type::NUM, "value",
165 "The value in " + Currency::get().ticker},
166 {RPCResult::Type::NUM, "n", "index"},
168 "scriptPubKey",
169 "",
170 {
171 {RPCResult::Type::STR, "asm", "the asm"},
172 {RPCResult::Type::STR, "hex", "the hex"},
173 {RPCResult::Type::NUM, "reqSigs",
174 "The required sigs"},
175 {RPCResult::Type::STR, "type",
176 "The type, eg 'pubkeyhash'"},
178 "addresses",
179 "",
180 {
181 {RPCResult::Type::STR, "address",
182 "bitcoin address"},
183 }},
184 }},
185 }},
186 }},
187 {RPCResult::Type::STR_HEX, "blockhash", "the block hash"},
188 {RPCResult::Type::NUM, "confirmations",
189 "The confirmations"},
190 {RPCResult::Type::NUM_TIME, "blocktime",
191 "The block time expressed in " + UNIX_EPOCH_TIME},
192 {RPCResult::Type::NUM, "time", "Same as \"blocktime\""},
193 }},
194 },
195 RPCExamples{HelpExampleCli("getrawtransaction", "\"mytxid\"") +
196 HelpExampleCli("getrawtransaction", "\"mytxid\" true") +
197 HelpExampleRpc("getrawtransaction", "\"mytxid\", true") +
198 HelpExampleCli("getrawtransaction",
199 "\"mytxid\" false \"myblockhash\"") +
200 HelpExampleCli("getrawtransaction",
201 "\"mytxid\" true \"myblockhash\"")},
202 [&](const RPCHelpMan &self, const Config &config,
203 const JSONRPCRequest &request) -> UniValue {
204 const NodeContext &node = EnsureAnyNodeContext(request.context);
206
207 bool in_active_chain = true;
208 TxId txid = TxId(ParseHashV(request.params[0], "parameter 1"));
209 const CBlockIndex *blockindex = nullptr;
210
211 const CChainParams &params = config.GetChainParams();
212 if (txid == params.GenesisBlock().hashMerkleRoot) {
213 // Special exception for the genesis block coinbase transaction
214 throw JSONRPCError(
216 "The genesis block coinbase is not considered an "
217 "ordinary transaction and cannot be retrieved");
218 }
219
220 // Accept either a bool (true) or a num (>=1) to indicate verbose
221 // output.
222 bool fVerbose = false;
223 if (!request.params[1].isNull()) {
224 fVerbose = request.params[1].isNum()
225 ? (request.params[1].getInt<int>() != 0)
226 : request.params[1].get_bool();
227 }
228
229 if (!request.params[2].isNull()) {
230 LOCK(cs_main);
231
232 BlockHash blockhash(
233 ParseHashV(request.params[2], "parameter 3"));
234 blockindex = chainman.m_blockman.LookupBlockIndex(blockhash);
235 if (!blockindex) {
237 "Block hash not found");
238 }
239 in_active_chain = chainman.ActiveChain().Contains(blockindex);
240 }
241
242 bool f_txindex_ready = false;
243 if (g_txindex && !blockindex) {
244 f_txindex_ready = g_txindex->BlockUntilSyncedToCurrentChain();
245 }
246
248 const CTransactionRef tx =
249 GetTransaction(blockindex, node.mempool.get(), txid, hash_block,
250 chainman.m_blockman);
251 if (!tx) {
252 std::string errmsg;
253 if (blockindex) {
255 return !blockindex->nStatus.hasData())) {
257 "Block not available");
258 }
259 errmsg = "No such transaction found in the provided block";
260 } else if (!g_txindex) {
261 errmsg =
262 "No such mempool transaction. Use -txindex or provide "
263 "a block hash to enable blockchain transaction queries";
264 } else if (!f_txindex_ready) {
265 errmsg = "No such mempool transaction. Blockchain "
266 "transactions are still in the process of being "
267 "indexed";
268 } else {
269 errmsg = "No such mempool or blockchain transaction";
270 }
271 throw JSONRPCError(
273 errmsg + ". Use gettransaction for wallet transactions.");
274 }
275
276 if (!fVerbose) {
277 return EncodeHexTx(*tx, RPCSerializationFlags());
278 }
279
280 UniValue result(UniValue::VOBJ);
281 if (blockindex) {
282 result.pushKV("in_active_chain", in_active_chain);
283 }
284 TxToJSON(*tx, hash_block, result, chainman.ActiveChainstate());
285 return result;
286 },
287 };
288}
289
291 return RPCHelpMan{
292 "createrawtransaction",
293 "Create a transaction spending the given inputs and creating new "
294 "outputs.\n"
295 "Outputs can be addresses or data.\n"
296 "Returns hex-encoded raw transaction.\n"
297 "Note that the transaction's inputs are not signed, and\n"
298 "it is not stored in the wallet or transmitted to the network.\n",
299 {
300 {
301 "inputs",
304 "The inputs",
305 {
306 {
307 "",
310 "",
311 {
312 {"txid", RPCArg::Type::STR_HEX,
313 RPCArg::Optional::NO, "The transaction id"},
315 "The output number"},
316 {"sequence", RPCArg::Type::NUM,
317 RPCArg::DefaultHint{"depends on the value of the "
318 "'locktime' argument"},
319 "The sequence number"},
320 },
321 },
322 },
323 },
324 {"outputs",
327 "The outputs (key-value pairs), where none of "
328 "the keys are duplicated.\n"
329 "That is, each address can only appear once and there can only "
330 "be one 'data' object.\n"
331 "For compatibility reasons, a dictionary, which holds the "
332 "key-value pairs directly, is also\n"
333 " accepted as second parameter.",
334 {
335 {
336 "",
339 "",
340 {
342 "A key-value pair. The key (string) is the "
343 "bitcoin address, the value (float or string) is "
344 "the amount in " +
346 },
347 },
348 {
349 "",
352 "",
353 {
355 "A key-value pair. The key must be \"data\", the "
356 "value is hex-encoded data"},
357 },
358 },
359 },
361 {"locktime", RPCArg::Type::NUM, RPCArg::Default{0},
362 "Raw locktime. Non-0 value also locktime-activates inputs"},
363 },
364 RPCResult{RPCResult::Type::STR_HEX, "transaction",
365 "hex string of the transaction"},
367 HelpExampleCli("createrawtransaction",
368 "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
369 "\" \"[{\\\"address\\\":10000.00}]\"") +
370 HelpExampleCli("createrawtransaction",
371 "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
372 "\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") +
373 HelpExampleRpc("createrawtransaction",
374 "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
375 "\", \"[{\\\"address\\\":10000.00}]\"") +
376 HelpExampleRpc("createrawtransaction",
377 "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
378 "\", \"[{\\\"data\\\":\\\"00010203\\\"}]\"")},
379 [&](const RPCHelpMan &self, const Config &config,
380 const JSONRPCRequest &request) -> UniValue {
382 ConstructTransaction(config.GetChainParams(), request.params[0],
383 request.params[1], request.params[2]);
384
386 },
387 };
388}
389
391 return RPCHelpMan{
392 "decoderawtransaction",
393 "Return a JSON object representing the serialized, hex-encoded "
394 "transaction.\n",
395 {
397 "The transaction hex string"},
398 },
399 RPCResult{
401 "",
402 "",
403 {
404 {RPCResult::Type::STR_HEX, "txid", "The transaction id"},
405 {RPCResult::Type::STR_HEX, "hash", "The transaction hash"},
406 {RPCResult::Type::NUM, "size", "The transaction size"},
407 {RPCResult::Type::NUM, "version", "The version"},
408 {RPCResult::Type::NUM_TIME, "locktime", "The lock time"},
410 "vin",
411 "",
412 {
414 "",
415 "",
416 {
418 "The transaction id"},
419 {RPCResult::Type::NUM, "vout", "The output number"},
421 "scriptSig",
422 "The script",
423 {
424 {RPCResult::Type::STR, "asm", "asm"},
425 {RPCResult::Type::STR_HEX, "hex", "hex"},
426 }},
427 {RPCResult::Type::NUM, "sequence",
428 "The script sequence number"},
429 }},
430 }},
432 "vout",
433 "",
434 {
436 "",
437 "",
438 {
439 {RPCResult::Type::NUM, "value",
440 "The value in " + Currency::get().ticker},
441 {RPCResult::Type::NUM, "n", "index"},
443 "scriptPubKey",
444 "",
445 {
446 {RPCResult::Type::STR, "asm", "the asm"},
447 {RPCResult::Type::STR_HEX, "hex", "the hex"},
448 {RPCResult::Type::NUM, "reqSigs",
449 "The required sigs"},
450 {RPCResult::Type::STR, "type",
451 "The type, eg 'pubkeyhash'"},
453 "addresses",
454 "",
455 {
456 {RPCResult::Type::STR, "address",
457 "bitcoin address"},
458 }},
459 }},
460 }},
461 }},
462 }},
463 RPCExamples{HelpExampleCli("decoderawtransaction", "\"hexstring\"") +
464 HelpExampleRpc("decoderawtransaction", "\"hexstring\"")},
465 [&](const RPCHelpMan &self, const Config &config,
466 const JSONRPCRequest &request) -> UniValue {
468
469 if (!DecodeHexTx(mtx, request.params[0].get_str())) {
471 "TX decode failed");
472 }
473
474 UniValue result(UniValue::VOBJ);
475 TxToUniv(CTransaction(std::move(mtx)), BlockHash(), result, false);
476
477 return result;
478 },
479 };
480}
481
483 return RPCHelpMan{
484 "decodescript",
485 "Decode a hex-encoded script.\n",
486 {
488 "the hex-encoded script"},
489 },
490 RPCResult{
492 "",
493 "",
494 {
495 {RPCResult::Type::STR, "asm", "Script public key"},
496 {RPCResult::Type::STR, "type",
497 "The output type (e.g. " + GetAllOutputTypes() + ")"},
498 {RPCResult::Type::NUM, "reqSigs", "The required signatures"},
500 "addresses",
501 "",
502 {
503 {RPCResult::Type::STR, "address", "bitcoin address"},
504 }},
505 {RPCResult::Type::STR, "p2sh",
506 "address of P2SH script wrapping this redeem script (not "
507 "returned if the script is already a P2SH)"},
508 }},
509 RPCExamples{HelpExampleCli("decodescript", "\"hexstring\"") +
510 HelpExampleRpc("decodescript", "\"hexstring\"")},
511 [&](const RPCHelpMan &self, const Config &config,
512 const JSONRPCRequest &request) -> UniValue {
514 CScript script;
515 if (request.params[0].get_str().size() > 0) {
516 std::vector<uint8_t> scriptData(
517 ParseHexV(request.params[0], "argument"));
518 script = CScript(scriptData.begin(), scriptData.end());
519 } else {
520 // Empty scripts are valid.
521 }
522
523 ScriptPubKeyToUniv(script, r, /* fIncludeHex */ false);
524
525 UniValue type;
526 type = r.find_value("type");
527
528 if (type.isStr() && type.get_str() != "scripthash") {
529 // P2SH cannot be wrapped in a P2SH. If this script is already a
530 // P2SH, don't return the address for a P2SH of the P2SH.
531 r.pushKV("p2sh", EncodeDestination(ScriptHash(script), config));
532 }
533
534 return r;
535 },
536 };
537}
538
540 return RPCHelpMan{
541 "combinerawtransaction",
542 "Combine multiple partially signed transactions into one "
543 "transaction.\n"
544 "The combined transaction may be another partially signed transaction "
545 "or a \n"
546 "fully signed transaction.",
547 {
548 {
549 "txs",
552 "The hex strings of partially signed "
553 "transactions",
554 {
555 {"hexstring", RPCArg::Type::STR_HEX,
557 "A hex-encoded raw transaction"},
558 },
559 },
560 },
562 "The hex-encoded raw transaction with signature(s)"},
563 RPCExamples{HelpExampleCli("combinerawtransaction",
564 R"('["myhex1", "myhex2", "myhex3"]')")},
565 [&](const RPCHelpMan &self, const Config &config,
566 const JSONRPCRequest &request) -> UniValue {
567 UniValue txs = request.params[0].get_array();
568 std::vector<CMutableTransaction> txVariants(txs.size());
569
570 for (unsigned int idx = 0; idx < txs.size(); idx++) {
571 if (!DecodeHexTx(txVariants[idx], txs[idx].get_str())) {
572 throw JSONRPCError(
574 strprintf("TX decode failed for tx %d", idx));
575 }
576 }
577
578 if (txVariants.empty()) {
580 "Missing transactions");
581 }
582
583 // mergedTx will end up with all the signatures; it
584 // starts as a clone of the rawtx:
586
587 // Fetch previous transactions (inputs):
590 {
591 NodeContext &node = EnsureAnyNodeContext(request.context);
592 const CTxMemPool &mempool = EnsureMemPool(node);
594 LOCK2(cs_main, mempool.cs);
596 chainman.ActiveChainstate().CoinsTip();
598 // temporarily switch cache backend to db+mempool view
599 view.SetBackend(viewMempool);
600
601 for (const CTxIn &txin : mergedTx.vin) {
602 // Load entries from viewChain into view; can fail.
603 view.AccessCoin(txin.prevout);
604 }
605
606 // switch back to avoid locking mempool for too long
607 view.SetBackend(viewDummy);
608 }
609
610 // Use CTransaction for the constant parts of the
611 // transaction to avoid rehashing.
613 // Sign what we can:
614 for (size_t i = 0; i < mergedTx.vin.size(); i++) {
615 CTxIn &txin = mergedTx.vin[i];
616 const Coin &coin = view.AccessCoin(txin.prevout);
617 if (coin.IsSpent()) {
619 "Input not found or already spent");
620 }
621 SignatureData sigdata;
622
623 const CTxOut &txout = coin.GetTxOut();
624
625 // ... and merge in other signatures:
626 for (const CMutableTransaction &txv : txVariants) {
627 if (txv.vin.size() > i) {
628 sigdata.MergeSignatureData(
629 DataFromTransaction(txv, i, txout));
630 }
631 }
634 &mergedTx, i, txout.nValue),
635 txout.scriptPubKey, sigdata);
636
637 UpdateInput(txin, sigdata);
638 }
639
641 },
642 };
643}
644
646 return RPCHelpMan{
647 "signrawtransactionwithkey",
648 "Sign inputs for raw transaction (serialized, hex-encoded).\n"
649 "The second argument is an array of base58-encoded private\n"
650 "keys that will be the only keys used to sign the transaction.\n"
651 "The third optional argument (may be null) is an array of previous "
652 "transaction outputs that\n"
653 "this transaction depends on but may not yet be in the block chain.\n",
654 {
656 "The transaction hex string"},
657 {
658 "privkeys",
661 "The base58-encoded private keys for signing",
662 {
664 "private key in base58-encoding"},
665 },
666 },
667 {
668 "prevtxs",
671 "The previous dependent transaction outputs",
672 {
673 {
674 "",
677 "",
678 {
679 {"txid", RPCArg::Type::STR_HEX,
680 RPCArg::Optional::NO, "The transaction id"},
682 "The output number"},
683 {"scriptPubKey", RPCArg::Type::STR_HEX,
684 RPCArg::Optional::NO, "script key"},
685 {"redeemScript", RPCArg::Type::STR_HEX,
687 "(required for P2SH) redeem script"},
688 {"amount", RPCArg::Type::AMOUNT,
689 RPCArg::Optional::NO, "The amount spent"},
690 },
691 },
692 },
693 },
694 {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"ALL|FORKID"},
695 "The signature hash type. Must be one of:\n"
696 " \"ALL|FORKID\"\n"
697 " \"NONE|FORKID\"\n"
698 " \"SINGLE|FORKID\"\n"
699 " \"ALL|FORKID|ANYONECANPAY\"\n"
700 " \"NONE|FORKID|ANYONECANPAY\"\n"
701 " \"SINGLE|FORKID|ANYONECANPAY\""},
702 },
703 RPCResult{
705 "",
706 "",
707 {
709 "The hex-encoded raw transaction with signature(s)"},
710 {RPCResult::Type::BOOL, "complete",
711 "If the transaction has a complete set of signatures"},
713 "errors",
714 /* optional */ true,
715 "Script verification errors (if there are any)",
716 {
718 "",
719 "",
720 {
722 "The hash of the referenced, previous transaction"},
723 {RPCResult::Type::NUM, "vout",
724 "The index of the output to spent and used as "
725 "input"},
726 {RPCResult::Type::STR_HEX, "scriptSig",
727 "The hex-encoded signature script"},
728 {RPCResult::Type::NUM, "sequence",
729 "Script sequence number"},
730 {RPCResult::Type::STR, "error",
731 "Verification or signing error related to the "
732 "input"},
733 }},
734 }},
735 }},
737 HelpExampleCli("signrawtransactionwithkey",
738 "\"myhex\" \"[\\\"key1\\\",\\\"key2\\\"]\"") +
739 HelpExampleRpc("signrawtransactionwithkey",
740 "\"myhex\", \"[\\\"key1\\\",\\\"key2\\\"]\"")},
741 [&](const RPCHelpMan &self, const Config &config,
742 const JSONRPCRequest &request) -> UniValue {
744 if (!DecodeHexTx(mtx, request.params[0].get_str())) {
746 "TX decode failed");
747 }
748
750 const UniValue &keys = request.params[1].get_array();
751 for (size_t idx = 0; idx < keys.size(); ++idx) {
752 UniValue k = keys[idx];
753 CKey key = DecodeSecret(k.get_str());
754 if (!key.IsValid()) {
756 "Invalid private key");
757 }
758 keystore.AddKey(key);
759 }
760
761 // Fetch previous transactions (inputs):
762 std::map<COutPoint, Coin> coins;
763 for (const CTxIn &txin : mtx.vin) {
764 // Create empty map entry keyed by prevout.
765 coins[txin.prevout];
766 }
767 NodeContext &node = EnsureAnyNodeContext(request.context);
768 FindCoins(node, coins);
769
770 // Parse the prevtxs array
771 ParsePrevouts(request.params[2], &keystore, coins);
772
773 UniValue result(UniValue::VOBJ);
774 SignTransaction(mtx, &keystore, coins, request.params[3], result);
775 return result;
776 },
777 };
778}
779
781 return RPCHelpMan{
782 "decodepsbt",
783 "Return a JSON object representing the serialized, base64-encoded "
784 "partially signed Bitcoin transaction.\n",
785 {
787 "The PSBT base64 string"},
788 },
789 RPCResult{
791 "",
792 "",
793 {
795 "tx",
796 "The decoded network-serialized unsigned transaction.",
797 {
799 "The layout is the same as the output of "
800 "decoderawtransaction."},
801 }},
803 "unknown",
804 "The unknown global fields",
805 {
807 "(key-value pair) An unknown key-value pair"},
808 }},
810 "inputs",
811 "",
812 {
814 "",
815 "",
816 {
818 "utxo",
819 /* optional */ true,
820 "Transaction output for UTXOs",
821 {
822 {RPCResult::Type::NUM, "amount",
823 "The value in " + Currency::get().ticker},
825 "scriptPubKey",
826 "",
827 {
828 {RPCResult::Type::STR, "asm", "The asm"},
830 "The hex"},
831 {RPCResult::Type::STR, "type",
832 "The type, eg 'pubkeyhash'"},
833 {RPCResult::Type::STR, "address",
834 " Bitcoin address if there is one"},
835 }},
836 }},
838 "partial_signatures",
839 /* optional */ true,
840 "",
841 {
842 {RPCResult::Type::STR, "pubkey",
843 "The public key and signature that corresponds "
844 "to it."},
845 }},
846 {RPCResult::Type::STR, "sighash", /* optional */ true,
847 "The sighash type to be used"},
849 "redeem_script",
850 /* optional */ true,
851 "",
852 {
853 {RPCResult::Type::STR, "asm", "The asm"},
854 {RPCResult::Type::STR_HEX, "hex", "The hex"},
855 {RPCResult::Type::STR, "type",
856 "The type, eg 'pubkeyhash'"},
857 }},
859 "bip32_derivs",
860 /* optional */ true,
861 "",
862 {
864 "pubkey",
865 /* optional */ true,
866 "The public key with the derivation path as "
867 "the value.",
868 {
869 {RPCResult::Type::STR, "master_fingerprint",
870 "The fingerprint of the master key"},
871 {RPCResult::Type::STR, "path", "The path"},
872 }},
873 }},
875 "final_scriptsig",
876 /* optional */ true,
877 "",
878 {
879 {RPCResult::Type::STR, "asm", "The asm"},
880 {RPCResult::Type::STR, "hex", "The hex"},
881 }},
883 "unknown",
884 "The unknown global fields",
885 {
887 "(key-value pair) An unknown key-value pair"},
888 }},
889 }},
890 }},
892 "outputs",
893 "",
894 {
896 "",
897 "",
898 {
900 "redeem_script",
901 /* optional */ true,
902 "",
903 {
904 {RPCResult::Type::STR, "asm", "The asm"},
905 {RPCResult::Type::STR_HEX, "hex", "The hex"},
906 {RPCResult::Type::STR, "type",
907 "The type, eg 'pubkeyhash'"},
908 }},
910 "bip32_derivs",
911 /* optional */ true,
912 "",
913 {
915 "",
916 "",
917 {
918 {RPCResult::Type::STR, "pubkey",
919 "The public key this path corresponds to"},
920 {RPCResult::Type::STR, "master_fingerprint",
921 "The fingerprint of the master key"},
922 {RPCResult::Type::STR, "path", "The path"},
923 }},
924 }},
926 "unknown",
927 "The unknown global fields",
928 {
930 "(key-value pair) An unknown key-value pair"},
931 }},
932 }},
933 }},
934 {RPCResult::Type::STR_AMOUNT, "fee", /* optional */ true,
935 "The transaction fee paid if all UTXOs slots in the PSBT have "
936 "been filled."},
937 }},
938 RPCExamples{HelpExampleCli("decodepsbt", "\"psbt\"")},
939 [&](const RPCHelpMan &self, const Config &config,
940 const JSONRPCRequest &request) -> UniValue {
941 // Unserialize the transactions
943 std::string error;
944 if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
946 strprintf("TX decode failed %s", error));
947 }
948
949 UniValue result(UniValue::VOBJ);
950
951 // Add the decoded tx
954 result.pushKV("tx", tx_univ);
955
956 // Unknown data
957 if (psbtx.unknown.size() > 0) {
959 for (auto entry : psbtx.unknown) {
960 unknowns.pushKV(HexStr(entry.first), HexStr(entry.second));
961 }
962 result.pushKV("unknown", unknowns);
963 }
964
965 // inputs
967 bool have_all_utxos = true;
968 UniValue inputs(UniValue::VARR);
969 for (size_t i = 0; i < psbtx.inputs.size(); ++i) {
970 const PSBTInput &input = psbtx.inputs[i];
972 // UTXOs
973 if (!input.utxo.IsNull()) {
974 const CTxOut &txout = input.utxo;
975
977
978 out.pushKV("amount", txout.nValue);
979 if (MoneyRange(txout.nValue) &&
980 MoneyRange(total_in + txout.nValue)) {
981 total_in += txout.nValue;
982 } else {
983 // Hack to just not show fee later
984 have_all_utxos = false;
985 }
986
988 ScriptToUniv(txout.scriptPubKey, o, true);
989 out.pushKV("scriptPubKey", o);
990 in.pushKV("utxo", out);
991 } else {
992 have_all_utxos = false;
993 }
994
995 // Partial sigs
996 if (!input.partial_sigs.empty()) {
997 UniValue partial_sigs(UniValue::VOBJ);
998 for (const auto &sig : input.partial_sigs) {
999 partial_sigs.pushKV(HexStr(sig.second.first),
1000 HexStr(sig.second.second));
1001 }
1002 in.pushKV("partial_signatures", partial_sigs);
1003 }
1004
1005 // Sighash
1007 input.sighash_type.getRawSigHashType() & 0xff;
1008 if (sighashbyte > 0) {
1009 in.pushKV("sighash", SighashToStr(sighashbyte));
1010 }
1011
1012 // Redeem script
1013 if (!input.redeem_script.empty()) {
1015 ScriptToUniv(input.redeem_script, r, false);
1016 in.pushKV("redeem_script", r);
1017 }
1018
1019 // keypaths
1020 if (!input.hd_keypaths.empty()) {
1022 for (auto entry : input.hd_keypaths) {
1024 keypath.pushKV("pubkey", HexStr(entry.first));
1025
1026 keypath.pushKV(
1027 "master_fingerprint",
1028 strprintf("%08x",
1029 ReadBE32(entry.second.fingerprint)));
1030 keypath.pushKV("path",
1031 WriteHDKeypath(entry.second.path));
1032 keypaths.push_back(keypath);
1033 }
1034 in.pushKV("bip32_derivs", keypaths);
1035 }
1036
1037 // Final scriptSig
1038 if (!input.final_script_sig.empty()) {
1040 scriptsig.pushKV(
1041 "asm", ScriptToAsmStr(input.final_script_sig, true));
1042 scriptsig.pushKV("hex", HexStr(input.final_script_sig));
1043 in.pushKV("final_scriptSig", scriptsig);
1044 }
1045
1046 // Unknown data
1047 if (input.unknown.size() > 0) {
1049 for (auto entry : input.unknown) {
1050 unknowns.pushKV(HexStr(entry.first),
1051 HexStr(entry.second));
1052 }
1053 in.pushKV("unknown", unknowns);
1054 }
1055
1056 inputs.push_back(in);
1057 }
1058 result.pushKV("inputs", inputs);
1059
1060 // outputs
1062 UniValue outputs(UniValue::VARR);
1063 for (size_t i = 0; i < psbtx.outputs.size(); ++i) {
1064 const PSBTOutput &output = psbtx.outputs[i];
1066 // Redeem script
1067 if (!output.redeem_script.empty()) {
1069 ScriptToUniv(output.redeem_script, r, false);
1070 out.pushKV("redeem_script", r);
1071 }
1072
1073 // keypaths
1074 if (!output.hd_keypaths.empty()) {
1076 for (auto entry : output.hd_keypaths) {
1078 keypath.pushKV("pubkey", HexStr(entry.first));
1079 keypath.pushKV(
1080 "master_fingerprint",
1081 strprintf("%08x",
1082 ReadBE32(entry.second.fingerprint)));
1083 keypath.pushKV("path",
1084 WriteHDKeypath(entry.second.path));
1085 keypaths.push_back(keypath);
1086 }
1087 out.pushKV("bip32_derivs", keypaths);
1088 }
1089
1090 // Unknown data
1091 if (output.unknown.size() > 0) {
1093 for (auto entry : output.unknown) {
1094 unknowns.pushKV(HexStr(entry.first),
1095 HexStr(entry.second));
1096 }
1097 out.pushKV("unknown", unknowns);
1098 }
1099
1100 outputs.push_back(out);
1101
1102 // Fee calculation
1103 if (MoneyRange(psbtx.tx->vout[i].nValue) &&
1104 MoneyRange(output_value + psbtx.tx->vout[i].nValue)) {
1105 output_value += psbtx.tx->vout[i].nValue;
1106 } else {
1107 // Hack to just not show fee later
1108 have_all_utxos = false;
1109 }
1110 }
1111 result.pushKV("outputs", outputs);
1112 if (have_all_utxos) {
1113 result.pushKV("fee", total_in - output_value);
1114 }
1115
1116 return result;
1117 },
1118 };
1119}
1120
1122 return RPCHelpMan{
1123 "combinepsbt",
1124 "Combine multiple partially signed Bitcoin transactions into one "
1125 "transaction.\n"
1126 "Implements the Combiner role.\n",
1127 {
1128 {
1129 "txs",
1132 "The base64 strings of partially signed transactions",
1133 {
1135 "A base64 string of a PSBT"},
1136 },
1137 },
1138 },
1140 "The base64-encoded partially signed transaction"},
1142 "combinepsbt", R"('["mybase64_1", "mybase64_2", "mybase64_3"]')")},
1143 [&](const RPCHelpMan &self, const Config &config,
1144 const JSONRPCRequest &request) -> UniValue {
1145 // Unserialize the transactions
1146 std::vector<PartiallySignedTransaction> psbtxs;
1147 UniValue txs = request.params[0].get_array();
1148 if (txs.empty()) {
1150 "Parameter 'txs' cannot be empty");
1151 }
1152 for (size_t i = 0; i < txs.size(); ++i) {
1154 std::string error;
1155 if (!DecodeBase64PSBT(psbtx, txs[i].get_str(), error)) {
1157 strprintf("TX decode failed %s", error));
1158 }
1159 psbtxs.push_back(psbtx);
1160 }
1161
1164 if (error != TransactionError::OK) {
1166 }
1167
1169 ssTx << merged_psbt;
1170 return EncodeBase64(ssTx);
1171 },
1172 };
1173}
1174
1176 return RPCHelpMan{
1177 "finalizepsbt",
1178 "Finalize the inputs of a PSBT. If the transaction is fully signed, it "
1179 "will produce a\n"
1180 "network serialized transaction which can be broadcast with "
1181 "sendrawtransaction. Otherwise a PSBT will be\n"
1182 "created which has the final_scriptSigfields filled for inputs that "
1183 "are complete.\n"
1184 "Implements the Finalizer and Extractor roles.\n",
1185 {
1187 "A base64 string of a PSBT"},
1188 {"extract", RPCArg::Type::BOOL, RPCArg::Default{true},
1189 "If true and the transaction is complete,\n"
1190 " extract and return the complete "
1191 "transaction in normal network serialization instead of the "
1192 "PSBT."},
1193 },
1195 "",
1196 "",
1197 {
1198 {RPCResult::Type::STR, "psbt",
1199 "The base64-encoded partially signed transaction if not "
1200 "extracted"},
1202 "The hex-encoded network transaction if extracted"},
1203 {RPCResult::Type::BOOL, "complete",
1204 "If the transaction has a complete set of signatures"},
1205 }},
1206 RPCExamples{HelpExampleCli("finalizepsbt", "\"psbt\"")},
1207 [&](const RPCHelpMan &self, const Config &config,
1208 const JSONRPCRequest &request) -> UniValue {
1209 // Unserialize the transactions
1211 std::string error;
1212 if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
1214 strprintf("TX decode failed %s", error));
1215 }
1216
1217 bool extract =
1218 request.params[1].isNull() ||
1219 (!request.params[1].isNull() && request.params[1].get_bool());
1220
1222 bool complete = FinalizeAndExtractPSBT(psbtx, mtx);
1223
1224 UniValue result(UniValue::VOBJ);
1226 std::string result_str;
1227
1228 if (complete && extract) {
1229 ssTx << mtx;
1231 result.pushKV("hex", result_str);
1232 } else {
1233 ssTx << psbtx;
1234 result_str = EncodeBase64(ssTx.str());
1235 result.pushKV("psbt", result_str);
1236 }
1237 result.pushKV("complete", complete);
1238
1239 return result;
1240 },
1241 };
1242}
1243
1245 return RPCHelpMan{
1246 "createpsbt",
1247 "Creates a transaction in the Partially Signed Transaction format.\n"
1248 "Implements the Creator role.\n",
1249 {
1250 {
1251 "inputs",
1254 "The json objects",
1255 {
1256 {
1257 "",
1260 "",
1261 {
1262 {"txid", RPCArg::Type::STR_HEX,
1263 RPCArg::Optional::NO, "The transaction id"},
1265 "The output number"},
1266 {"sequence", RPCArg::Type::NUM,
1267 RPCArg::DefaultHint{"depends on the value of the "
1268 "'locktime' argument"},
1269 "The sequence number"},
1270 },
1271 },
1272 },
1273 },
1274 {"outputs",
1277 "The outputs (key-value pairs), where none of "
1278 "the keys are duplicated.\n"
1279 "That is, each address can only appear once and there can only "
1280 "be one 'data' object.\n"
1281 "For compatibility reasons, a dictionary, which holds the "
1282 "key-value pairs directly, is also\n"
1283 " accepted as second parameter.",
1284 {
1285 {
1286 "",
1289 "",
1290 {
1292 "A key-value pair. The key (string) is the "
1293 "bitcoin address, the value (float or string) is "
1294 "the amount in " +
1296 },
1297 },
1298 {
1299 "",
1302 "",
1303 {
1305 "A key-value pair. The key must be \"data\", the "
1306 "value is hex-encoded data"},
1307 },
1308 },
1309 },
1311 {"locktime", RPCArg::Type::NUM, RPCArg::Default{0},
1312 "Raw locktime. Non-0 value also locktime-activates inputs"},
1313 },
1315 "The resulting raw transaction (base64-encoded string)"},
1317 "createpsbt", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
1318 "\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"")},
1319 [&](const RPCHelpMan &self, const Config &config,
1320 const JSONRPCRequest &request) -> UniValue {
1322 ConstructTransaction(config.GetChainParams(), request.params[0],
1323 request.params[1], request.params[2]);
1324
1325 // Make a blank psbt
1327 psbtx.tx = rawTx;
1328 for (size_t i = 0; i < rawTx.vin.size(); ++i) {
1329 psbtx.inputs.push_back(PSBTInput());
1330 }
1331 for (size_t i = 0; i < rawTx.vout.size(); ++i) {
1332 psbtx.outputs.push_back(PSBTOutput());
1333 }
1334
1335 // Serialize the PSBT
1337 ssTx << psbtx;
1338
1339 return EncodeBase64(ssTx);
1340 },
1341 };
1342}
1343
1345 return RPCHelpMan{
1346 "converttopsbt",
1347 "Converts a network serialized transaction to a PSBT. "
1348 "This should be used only with createrawtransaction and "
1349 "fundrawtransaction\n"
1350 "createpsbt and walletcreatefundedpsbt should be used for new "
1351 "applications.\n",
1352 {
1354 "The hex string of a raw transaction"},
1355 {"permitsigdata", RPCArg::Type::BOOL, RPCArg::Default{false},
1356 "If true, any signatures in the input will be discarded and "
1357 "conversion.\n"
1358 " will continue. If false, RPC will "
1359 "fail if any signatures are present."},
1360 },
1362 "The resulting raw transaction (base64-encoded string)"},
1364 "\nCreate a transaction\n" +
1365 HelpExampleCli("createrawtransaction",
1366 "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]"
1367 "\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") +
1368 "\nConvert the transaction to a PSBT\n" +
1369 HelpExampleCli("converttopsbt", "\"rawtransaction\"")},
1370 [&](const RPCHelpMan &self, const Config &config,
1371 const JSONRPCRequest &request) -> UniValue {
1372 // parse hex string from parameter
1374 bool permitsigdata = request.params[1].isNull()
1375 ? false
1376 : request.params[1].get_bool();
1377 if (!DecodeHexTx(tx, request.params[0].get_str())) {
1379 "TX decode failed");
1380 }
1381
1382 // Remove all scriptSigs from inputs
1383 for (CTxIn &input : tx.vin) {
1384 if (!input.scriptSig.empty() && !permitsigdata) {
1386 "Inputs must not have scriptSigs");
1387 }
1388 input.scriptSig.clear();
1389 }
1390
1391 // Make a blank psbt
1393 psbtx.tx = tx;
1394 for (size_t i = 0; i < tx.vin.size(); ++i) {
1395 psbtx.inputs.push_back(PSBTInput());
1396 }
1397 for (size_t i = 0; i < tx.vout.size(); ++i) {
1398 psbtx.outputs.push_back(PSBTOutput());
1399 }
1400
1401 // Serialize the PSBT
1403 ssTx << psbtx;
1404
1405 return EncodeBase64(ssTx);
1406 },
1407 };
1408}
1409
1411 return RPCHelpMan{
1412 "utxoupdatepsbt",
1413 "Updates all inputs and outputs in a PSBT with data from output "
1414 "descriptors, the UTXO set or the mempool.\n",
1415 {
1417 "A base64 string of a PSBT"},
1418 {"descriptors",
1421 "An array of either strings or objects",
1422 {
1424 "An output descriptor"},
1425 {"",
1428 "An object with an output descriptor and extra information",
1429 {
1431 "An output descriptor"},
1432 {"range", RPCArg::Type::RANGE, RPCArg::Default{1000},
1433 "Up to what index HD chains should be explored (either "
1434 "end or [begin,end])"},
1435 }},
1436 }},
1437 },
1439 "The base64-encoded partially signed transaction with inputs "
1440 "updated"},
1441 RPCExamples{HelpExampleCli("utxoupdatepsbt", "\"psbt\"")},
1442 [&](const RPCHelpMan &self, const Config &config,
1443 const JSONRPCRequest &request) -> UniValue {
1444 // Unserialize the transactions
1446 std::string error;
1447 if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
1449 strprintf("TX decode failed %s", error));
1450 }
1451
1452 // Parse descriptors, if any.
1453 FlatSigningProvider provider;
1454 if (!request.params[1].isNull()) {
1455 auto descs = request.params[1].get_array();
1456 for (size_t i = 0; i < descs.size(); ++i) {
1457 EvalDescriptorStringOrObject(descs[i], provider);
1458 }
1459 }
1460 // We don't actually need private keys further on; hide them as a
1461 // precaution.
1462 HidingSigningProvider public_provider(&provider, /* nosign */ true,
1463 /* nobip32derivs */ false);
1464
1465 // Fetch previous transactions (inputs):
1468 {
1469 NodeContext &node = EnsureAnyNodeContext(request.context);
1470 const CTxMemPool &mempool = EnsureMemPool(node);
1472 LOCK2(cs_main, mempool.cs);
1474 chainman.ActiveChainstate().CoinsTip();
1476 // temporarily switch cache backend to db+mempool view
1477 view.SetBackend(viewMempool);
1478
1479 for (const CTxIn &txin : psbtx.tx->vin) {
1480 // Load entries from viewChain into view; can fail.
1481 view.AccessCoin(txin.prevout);
1482 }
1483
1484 // switch back to avoid locking mempool for too long
1485 view.SetBackend(viewDummy);
1486 }
1487
1488 // Fill the inputs
1489 for (size_t i = 0; i < psbtx.tx->vin.size(); ++i) {
1490 PSBTInput &input = psbtx.inputs.at(i);
1491
1492 if (!input.utxo.IsNull()) {
1493 continue;
1494 }
1495
1496 // Update script/keypath information using descriptor data.
1497 // Note that SignPSBTInput does a lot more than just
1498 // constructing ECDSA signatures we don't actually care about
1499 // those here, in fact.
1501 /* sighash_type */ SigHashType().withForkId());
1502 }
1503
1504 // Update script/keypath information using descriptor data.
1505 for (unsigned int i = 0; i < psbtx.tx->vout.size(); ++i) {
1507 }
1508
1510 ssTx << psbtx;
1511 return EncodeBase64(ssTx);
1512 },
1513 };
1514}
1515
1517 return RPCHelpMan{
1518 "joinpsbts",
1519 "Joins multiple distinct PSBTs with different inputs and outputs "
1520 "into one PSBT with inputs and outputs from all of the PSBTs\n"
1521 "No input in any of the PSBTs can be in more than one of the PSBTs.\n",
1522 {{"txs",
1525 "The base64 strings of partially signed transactions",
1527 "A base64 string of a PSBT"}}}},
1529 "The base64-encoded partially signed transaction"},
1530 RPCExamples{HelpExampleCli("joinpsbts", "\"psbt\"")},
1531 [&](const RPCHelpMan &self, const Config &config,
1532 const JSONRPCRequest &request) -> UniValue {
1533 // Unserialize the transactions
1534 std::vector<PartiallySignedTransaction> psbtxs;
1535 UniValue txs = request.params[0].get_array();
1536
1537 if (txs.size() <= 1) {
1538 throw JSONRPCError(
1540 "At least two PSBTs are required to join PSBTs.");
1541 }
1542
1544 uint32_t best_locktime = 0xffffffff;
1545 for (size_t i = 0; i < txs.size(); ++i) {
1547 std::string error;
1548 if (!DecodeBase64PSBT(psbtx, txs[i].get_str(), error)) {
1550 strprintf("TX decode failed %s", error));
1551 }
1552 psbtxs.push_back(psbtx);
1553 // Choose the highest version number
1554 if (static_cast<uint32_t>(psbtx.tx->nVersion) > best_version) {
1555 best_version = static_cast<uint32_t>(psbtx.tx->nVersion);
1556 }
1557 // Choose the lowest lock time
1558 if (psbtx.tx->nLockTime < best_locktime) {
1559 best_locktime = psbtx.tx->nLockTime;
1560 }
1561 }
1562
1563 // Create a blank psbt where everything will be added
1566 merged_psbt.tx->nVersion = static_cast<int32_t>(best_version);
1567 merged_psbt.tx->nLockTime = best_locktime;
1568
1569 // Merge
1570 for (auto &psbt : psbtxs) {
1571 for (size_t i = 0; i < psbt.tx->vin.size(); ++i) {
1572 if (!merged_psbt.AddInput(psbt.tx->vin[i],
1573 psbt.inputs[i])) {
1574 throw JSONRPCError(
1576 strprintf("Input %s:%d exists in multiple PSBTs",
1577 psbt.tx->vin[i]
1578 .prevout.GetTxId()
1579 .ToString()
1580 .c_str(),
1581 psbt.tx->vin[i].prevout.GetN()));
1582 }
1583 }
1584 for (size_t i = 0; i < psbt.tx->vout.size(); ++i) {
1585 merged_psbt.AddOutput(psbt.tx->vout[i], psbt.outputs[i]);
1586 }
1587 merged_psbt.unknown.insert(psbt.unknown.begin(),
1588 psbt.unknown.end());
1589 }
1590
1591 // Generate list of shuffled indices for shuffling inputs and
1592 // outputs of the merged PSBT
1593 std::vector<int> input_indices(merged_psbt.inputs.size());
1594 std::iota(input_indices.begin(), input_indices.end(), 0);
1595 std::vector<int> output_indices(merged_psbt.outputs.size());
1596 std::iota(output_indices.begin(), output_indices.end(), 0);
1597
1598 // Shuffle input and output indices lists
1599 Shuffle(input_indices.begin(), input_indices.end(),
1601 Shuffle(output_indices.begin(), output_indices.end(),
1603
1606 shuffled_psbt.tx->nVersion = merged_psbt.tx->nVersion;
1607 shuffled_psbt.tx->nLockTime = merged_psbt.tx->nLockTime;
1608 for (int i : input_indices) {
1609 shuffled_psbt.AddInput(merged_psbt.tx->vin[i],
1610 merged_psbt.inputs[i]);
1611 }
1612 for (int i : output_indices) {
1613 shuffled_psbt.AddOutput(merged_psbt.tx->vout[i],
1614 merged_psbt.outputs[i]);
1615 }
1616 shuffled_psbt.unknown.insert(merged_psbt.unknown.begin(),
1617 merged_psbt.unknown.end());
1618
1621 return EncodeBase64(ssTx);
1622 },
1623 };
1624}
1625
1627 return RPCHelpMan{
1628 "analyzepsbt",
1629 "Analyzes and provides information about the current status of a "
1630 "PSBT and its inputs\n",
1632 "A base64 string of a PSBT"}},
1633 RPCResult{
1635 "",
1636 "",
1637 {
1639 "inputs",
1640 "",
1641 {
1643 "",
1644 "",
1645 {
1646 {RPCResult::Type::BOOL, "has_utxo",
1647 "Whether a UTXO is provided"},
1648 {RPCResult::Type::BOOL, "is_final",
1649 "Whether the input is finalized"},
1651 "missing",
1652 /* optional */ true,
1653 "Things that are missing that are required to "
1654 "complete this input",
1655 {
1657 "pubkeys",
1658 /* optional */ true,
1659 "",
1660 {
1661 {RPCResult::Type::STR_HEX, "keyid",
1662 "Public key ID, hash160 of the public "
1663 "key, of a public key whose BIP 32 "
1664 "derivation path is missing"},
1665 }},
1667 "signatures",
1668 /* optional */ true,
1669 "",
1670 {
1671 {RPCResult::Type::STR_HEX, "keyid",
1672 "Public key ID, hash160 of the public "
1673 "key, of a public key whose signature is "
1674 "missing"},
1675 }},
1676 {RPCResult::Type::STR_HEX, "redeemscript",
1677 /* optional */ true,
1678 "Hash160 of the redeemScript that is missing"},
1679 }},
1680 {RPCResult::Type::STR, "next", /* optional */ true,
1681 "Role of the next person that this input needs to "
1682 "go to"},
1683 }},
1684 }},
1685 {RPCResult::Type::NUM, "estimated_vsize", /* optional */ true,
1686 "Estimated vsize of the final signed transaction"},
1687 {RPCResult::Type::STR_AMOUNT, "estimated_feerate",
1688 /* optional */ true,
1689 "Estimated feerate of the final signed transaction in " +
1691 "/kB. Shown only if all UTXO slots in the PSBT have been "
1692 "filled"},
1693 {RPCResult::Type::STR_AMOUNT, "fee", /* optional */ true,
1694 "The transaction fee paid. Shown only if all UTXO slots in "
1695 "the PSBT have been filled"},
1696 {RPCResult::Type::STR, "next",
1697 "Role of the next person that this psbt needs to go to"},
1698 {RPCResult::Type::STR, "error", /* optional */ true,
1699 "Error message (if there is one)"},
1700 }},
1701 RPCExamples{HelpExampleCli("analyzepsbt", "\"psbt\"")},
1702 [&](const RPCHelpMan &self, const Config &config,
1703 const JSONRPCRequest &request) -> UniValue {
1704 // Unserialize the transaction
1706 std::string error;
1707 if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
1709 strprintf("TX decode failed %s", error));
1710 }
1711
1712 PSBTAnalysis psbta = AnalyzePSBT(psbtx);
1713
1714 UniValue result(UniValue::VOBJ);
1716 for (const auto &input : psbta.inputs) {
1719
1720 input_univ.pushKV("has_utxo", input.has_utxo);
1721 input_univ.pushKV("is_final", input.is_final);
1722 input_univ.pushKV("next", PSBTRoleName(input.next));
1723
1724 if (!input.missing_pubkeys.empty()) {
1726 for (const CKeyID &pubkey : input.missing_pubkeys) {
1727 missing_pubkeys_univ.push_back(HexStr(pubkey));
1728 }
1729 missing.pushKV("pubkeys", missing_pubkeys_univ);
1730 }
1731 if (!input.missing_redeem_script.IsNull()) {
1732 missing.pushKV("redeemscript",
1733 HexStr(input.missing_redeem_script));
1734 }
1735 if (!input.missing_sigs.empty()) {
1737 for (const CKeyID &pubkey : input.missing_sigs) {
1738 missing_sigs_univ.push_back(HexStr(pubkey));
1739 }
1740 missing.pushKV("signatures", missing_sigs_univ);
1741 }
1742 if (!missing.getKeys().empty()) {
1743 input_univ.pushKV("missing", missing);
1744 }
1745 inputs_result.push_back(input_univ);
1746 }
1747 if (!inputs_result.empty()) {
1748 result.pushKV("inputs", inputs_result);
1749 }
1750 if (psbta.estimated_vsize != std::nullopt) {
1751 result.pushKV("estimated_vsize", (int)*psbta.estimated_vsize);
1752 }
1753 if (psbta.estimated_feerate != std::nullopt) {
1754 result.pushKV("estimated_feerate",
1755 psbta.estimated_feerate->GetFeePerK());
1756 }
1757 if (psbta.fee != std::nullopt) {
1758 result.pushKV("fee", *psbta.fee);
1759 }
1760 result.pushKV("next", PSBTRoleName(psbta.next));
1761 if (!psbta.error.empty()) {
1762 result.pushKV("error", psbta.error);
1763 }
1764
1765 return result;
1766 },
1767 };
1768}
1769
1771 return RPCHelpMan{
1772 "gettransactionstatus",
1773 "Return the current pool a transaction belongs to\n",
1774 {
1776 "The transaction id"},
1777 },
1778 RPCResult{
1780 "",
1781 "",
1782 {
1783 {RPCResult::Type::STR, "pool",
1784 "In which pool the transaction is currently located, "
1785 "either none, mempool, orphanage or conflicting"},
1786 {RPCResult::Type::STR, "block",
1787 "If the transaction is mined, this is the blockhash of the "
1788 "mining block, otherwise \"none\". This field is only "
1789 "present if -txindex is enabled."},
1790 }},
1791 RPCExamples{HelpExampleCli("gettransactionstatus", "\"txid\"")},
1792 [&](const RPCHelpMan &self, const Config &config,
1793 const JSONRPCRequest &request) -> UniValue {
1794 const NodeContext &node = EnsureAnyNodeContext(request.context);
1795 CTxMemPool &mempool = EnsureMemPool(node);
1796
1797 TxId txid = TxId(ParseHashV(request.params[0], "parameter 1"));
1798
1800
1801 if (mempool.exists(txid)) {
1802 ret.pushKV("pool", "mempool");
1803 } else if (mempool.withOrphanage(
1804 [&txid](const TxOrphanage &orphanage) {
1805 return orphanage.HaveTx(txid);
1806 })) {
1807 ret.pushKV("pool", "orphanage");
1808 } else if (mempool.withConflicting(
1809 [&txid](const TxConflicting &conflicting) {
1810 return conflicting.HaveTx(txid);
1811 })) {
1812 ret.pushKV("pool", "conflicting");
1813 } else {
1814 ret.pushKV("pool", "none");
1815 }
1816
1817 if (g_txindex) {
1818 if (!g_txindex->BlockUntilSyncedToCurrentChain()) {
1819 throw JSONRPCError(
1821 "Blockchain transactions are still in the process of "
1822 "being indexed");
1823 }
1824
1825 CTransactionRef tx;
1826 BlockHash blockhash;
1827 if (g_txindex->FindTx(txid, blockhash, tx)) {
1828 ret.pushKV("block", blockhash.GetHex());
1829 } else {
1830 ret.pushKV("block", "none");
1831 }
1832 }
1833
1834 return ret;
1835 },
1836 };
1837}
1838
1840 // clang-format off
1841 static const CRPCCommand commands[] = {
1842 // category actor (function)
1843 // ------------------ ----------------------
1844 { "rawtransactions", getrawtransaction, },
1845 { "rawtransactions", createrawtransaction, },
1846 { "rawtransactions", decoderawtransaction, },
1847 { "rawtransactions", decodescript, },
1848 { "rawtransactions", combinerawtransaction, },
1849 { "rawtransactions", signrawtransactionwithkey, },
1850 { "rawtransactions", decodepsbt, },
1851 { "rawtransactions", combinepsbt, },
1852 { "rawtransactions", finalizepsbt, },
1853 { "rawtransactions", createpsbt, },
1854 { "rawtransactions", converttopsbt, },
1855 { "rawtransactions", utxoupdatepsbt, },
1856 { "rawtransactions", joinpsbts, },
1857 { "rawtransactions", analyzepsbt, },
1858 { "rawtransactions", gettransactionstatus, },
1859 };
1860 // clang-format on
1861 for (const auto &c : commands) {
1862 t.appendCommand(c.name, &c);
1863 }
1864}
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:180
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition blockindex.h:38
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:80
const CBlock & GenesisBlock() const
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition coins.h:221
Abstract view on the open txout dataset.
Definition coins.h:163
CCoinsView that brings transactions from a mempool into view.
Definition txmempool.h:618
Double ended buffer combining vector and stream-like interfaces.
Definition streams.h:177
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.
std::vector< CTxOut > vout
std::vector< CTxIn > vin
RPC command dispatcher.
Definition server.h:194
Serialized script, used inside transaction inputs and outputs.
Definition script.h:424
The basic transaction that is broadcasted on the network and contained in blocks.
An input of a transaction.
Definition transaction.h:59
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition txmempool.h:212
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
Definition txmempool.h:307
bool exists(const TxId &txid) const
Definition txmempool.h:503
auto withOrphanage(Callable &&func) const EXCLUSIVE_LOCKS_REQUIRED(!cs_orphanage)
Definition txmempool.h:561
auto withConflicting(Callable &&func) const EXCLUSIVE_LOCKS_REQUIRED(!cs_conflicting)
Definition txmempool.h:569
An output of a transaction.
CScript scriptPubKey
Amount nValue
bool IsNull() const
Chainstate stores and provides an API to update our local knowledge of the current best chain.
Definition validation.h:699
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
SnapshotCompletionResult MaybeCompleteSnapshotValidation(std::function< void(bilingual_str)> shutdown_fnc=[](bilingual_str msg) { AbortNode(msg.original, msg);}) EXCLUSIVE_LOCKS_REQUIRED(Chainstate & ActiveChainstate() const
Once the background validation chainstate has reached the height which is the base of the UTXO snapsh...
CChain & ActiveChain() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
node::BlockManager m_blockman
A single BlockManager instance is shared across each constructed chainstate to avoid duplicating bloc...
A UTXO entry.
Definition coins.h:28
CTxOut & GetTxOut()
Definition coins.h:49
bool IsSpent() const
Definition coins.h:47
Fast randomness source.
Definition random.h:156
Fillable signing provider that keeps keys in an address->secret map.
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
size_t size() const
Definition univalue.h:92
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)
void TxToUniv(const CTransaction &tx, const BlockHash &hashBlock, UniValue &entry, bool include_hex=true, int serialize_flags=0, const CTxUndo *txundo=nullptr)
std::string SighashToStr(uint8_t sighash_type)
void ScriptPubKeyToUniv(const CScript &scriptPubKey, UniValue &out, bool fIncludeHex)
bool DecodeHexTx(CMutableTransaction &tx, const std::string &strHexTx)
std::string ScriptToAsmStr(const CScript &script, const bool fAttemptSighashDecode=false)
Create the assembly string representation of a CScript object.
std::string EncodeHexTx(const CTransaction &tx, const int serializeFlags=0)
static uint32_t ReadBE32(const uint8_t *ptr)
Definition common.h:56
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition cs_main.cpp:7
TransactionError
Definition error.h:22
std::string EncodeDestination(const CTxDestination &dest, const Config &config)
Definition key_io.cpp:167
CKey DecodeSecret(const std::string &str)
Definition key_io.cpp:77
bool error(const char *fmt, const Args &...args)
Definition logging.h:263
Definition init.h:28
PSBTAnalysis AnalyzePSBT(PartiallySignedTransaction psbtx)
Provides helpful miscellaneous information about where a PSBT is in the signing workflow.
Definition psbt.cpp:16
TransactionError BroadcastTransaction(const NodeContext &node, const CTransactionRef tx, std::string &err_string, const Amount max_tx_fee, bool relay, bool wait_callback)
Submit a transaction to the mempool and (optionally) relay it to all P2P peers.
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
SchnorrSig sig
bool DecodeBase64PSBT(PartiallySignedTransaction &psbt, const std::string &base64_tx, std::string &error)
Decode a base64ed PSBT into a PartiallySignedTransaction.
Definition psbt.cpp:296
void UpdatePSBTOutput(const SigningProvider &provider, PartiallySignedTransaction &psbt, int index)
Updates a PSBTOutput with information from provider.
Definition psbt.cpp:164
std::string PSBTRoleName(const PSBTRole role)
Definition psbt.cpp:279
bool FinalizeAndExtractPSBT(PartiallySignedTransaction &psbtx, CMutableTransaction &result)
Finalizes a PSBT if possible, and extracts it to a CMutableTransaction if it could be finalized.
Definition psbt.cpp:247
TransactionError CombinePSBTs(PartiallySignedTransaction &out, const std::vector< PartiallySignedTransaction > &psbtxs)
Combines PSBTs with the same underlying transaction, resulting in a single PSBT with all partial sign...
Definition psbt.cpp:264
bool SignPSBTInput(const SigningProvider &provider, PartiallySignedTransaction &psbt, int index, SigHashType sighash, SignatureData *out_sigdata, bool use_dummy)
Signs a PSBTInput, verifying that all provided data matches what is being signed.
Definition psbt.cpp:186
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
Definition random.h:291
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
Definition random.h:85
RPCHelpMan joinpsbts()
static RPCHelpMan getrawtransaction()
static RPCHelpMan converttopsbt()
RPCHelpMan analyzepsbt()
static RPCHelpMan decoderawtransaction()
static RPCHelpMan combinepsbt()
static RPCHelpMan decodepsbt()
RPCHelpMan gettransactionstatus()
static RPCHelpMan decodescript()
static RPCHelpMan createpsbt()
RPCHelpMan utxoupdatepsbt()
static RPCHelpMan combinerawtransaction()
static void TxToJSON(const CTransaction &tx, const BlockHash &hashBlock, UniValue &entry, Chainstate &active_chainstate)
static RPCHelpMan signrawtransactionwithkey()
static RPCHelpMan createrawtransaction()
static RPCHelpMan finalizepsbt()
void RegisterRawTransactionRPCCommands(CRPCTable &t)
void SignTransaction(CMutableTransaction &mtx, const SigningProvider *keystore, const std::map< COutPoint, Coin > &coins, const UniValue &hashType, UniValue &result)
Sign a transaction with the given keystore and previous transactions.
CMutableTransaction ConstructTransaction(const CChainParams &params, const UniValue &inputs_in, const UniValue &outputs_in, const UniValue &locktime)
Create a transaction from univalue parameters.
void ParsePrevouts(const UniValue &prevTxsUnival, FillableSigningProvider *keystore, std::map< COutPoint, Coin > &coins)
Parse a prevtxs UniValue array and get the map of coins from it.
UniValue JSONRPCError(int code, const std::string &message)
Definition request.cpp:58
@ RPC_MISC_ERROR
General application defined errors std::exception thrown in command handling.
Definition protocol.h:38
@ RPC_INVALID_PARAMETER
Invalid, missing or duplicate parameter.
Definition protocol.h:46
@ RPC_VERIFY_ERROR
General error during transaction or block submission.
Definition protocol.h:52
@ RPC_DESERIALIZATION_ERROR
Error parsing or validating structure in raw format.
Definition protocol.h:50
@ RPC_INVALID_ADDRESS_OR_KEY
Invalid address or key.
Definition protocol.h:42
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition util.cpp:150
UniValue JSONRPCTransactionError(TransactionError terr, const std::string &err_string)
Definition util.cpp:333
std::vector< uint8_t > ParseHexV(const UniValue &v, std::string strName)
Definition util.cpp:94
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition util.cpp:167
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:1290
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:22
std::string GetAllOutputTypes()
Definition util.cpp:305
uint256 ParseHashV(const UniValue &v, std::string strName)
Utilities: convert hex-encoded values (throws error if not hex).
Definition util.cpp:73
#define extract(n)
Extract the lowest 64 bits of (c0,c1,c2) into n, and left shift the number 64 bits.
@ SER_NETWORK
Definition serialize.h:152
int RPCSerializationFlags()
Retrieves any serialization flags requested in command line argument.
Definition server.cpp:679
NodeContext & EnsureAnyNodeContext(const std::any &context)
CTxMemPool & EnsureMemPool(const NodeContext &node)
ChainstateManager & EnsureChainman(const NodeContext &node)
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
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::optional< CMutableTransaction > tx
Definition psbt.h:335
@ 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:195
@ OMITTED
The arg is optional for one of two reasons:
@ NO
Required arg.
bool skip_type_check
Definition util.h:125
@ 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:43
Holds the results of AnalyzePSBT (miscellaneous information about a PSBT)
Definition psbt.h:35
#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...
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