Line data Source code
1 : // Copyright (c) 2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2022 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 <base58.h>
7 : #include <chain.h>
8 : #include <coins.h>
9 : #include <consensus/amount.h>
10 : #include <consensus/validation.h>
11 : #include <core_io.h>
12 : #include <index/txindex.h>
13 : #include <key_io.h>
14 : #include <node/blockstorage.h>
15 : #include <node/coin.h>
16 : #include <node/context.h>
17 2 : #include <node/psbt.h>
18 2 : #include <node/transaction.h>
19 : #include <policy/packages.h>
20 : #include <policy/policy.h>
21 : #include <policy/rbf.h>
22 : #include <primitives/transaction.h>
23 : #include <psbt.h>
24 : #include <random.h>
25 : #include <rpc/blockchain.h>
26 : #include <rpc/rawtransaction_util.h>
27 2 : #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>
32 : #include <script/signingprovider.h>
33 : #include <script/solver.h>
34 : #include <uint256.h>
35 : #include <undo.h>
36 : #include <util/bip32.h>
37 : #include <util/check.h>
38 : #include <util/strencodings.h>
39 : #include <util/string.h>
40 : #include <util/vector.h>
41 : #include <validation.h>
42 : #include <validationinterface.h>
43 :
44 : #include <numeric>
45 : #include <stdint.h>
46 :
47 : #include <univalue.h>
48 :
49 : using node::AnalyzePSBT;
50 : using node::FindCoins;
51 : using node::GetTransaction;
52 : using node::NodeContext;
53 : using node::PSBTAnalysis;
54 :
55 0 : static void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry,
56 : Chainstate& active_chainstate, const CTxUndo* txundo = nullptr,
57 : TxVerbosity verbosity = TxVerbosity::SHOW_DETAILS)
58 : {
59 0 : CHECK_NONFATAL(verbosity >= TxVerbosity::SHOW_DETAILS);
60 : // Call into TxToUniv() in bitcoin-common to decode the transaction hex.
61 : //
62 : // Blockchain contextual information (confirmations and blocktime) is not
63 : // available to code in bitcoin-common, so we query them here and push the
64 : // data into the returned UniValue.
65 0 : TxToUniv(tx, /*block_hash=*/uint256(), entry, /*include_hex=*/true, RPCSerializationFlags(), txundo, verbosity);
66 :
67 0 : if (!hashBlock.IsNull()) {
68 0 : LOCK(cs_main);
69 :
70 0 : entry.pushKV("blockhash", hashBlock.GetHex());
71 0 : const CBlockIndex* pindex = active_chainstate.m_blockman.LookupBlockIndex(hashBlock);
72 0 : if (pindex) {
73 0 : if (active_chainstate.m_chain.Contains(pindex)) {
74 2 : entry.pushKV("confirmations", 1 + active_chainstate.m_chain.Height() - pindex->nHeight);
75 0 : entry.pushKV("time", pindex->GetBlockTime());
76 0 : entry.pushKV("blocktime", pindex->GetBlockTime());
77 0 : }
78 : else
79 0 : entry.pushKV("confirmations", 0);
80 0 : }
81 0 : }
82 0 : }
83 :
84 6 : static std::vector<RPCResult> ScriptPubKeyDoc() {
85 6 : return
86 36 : {
87 6 : {RPCResult::Type::STR, "asm", "Disassembly of the public key script"},
88 6 : {RPCResult::Type::STR, "desc", "Inferred descriptor for the output"},
89 6 : {RPCResult::Type::STR_HEX, "hex", "The raw public key script bytes, hex-encoded"},
90 6 : {RPCResult::Type::STR, "address", /*optional=*/true, "The Bitcoin address (only if a well-defined address exists)"},
91 6 : {RPCResult::Type::STR, "type", "The type (one of: " + GetAllOutputTypes() + ")"},
92 : };
93 0 : }
94 :
95 4 : static std::vector<RPCResult> DecodeTxDoc(const std::string& txid_field_doc)
96 : {
97 40 : return {
98 4 : {RPCResult::Type::STR_HEX, "txid", txid_field_doc},
99 4 : {RPCResult::Type::STR_HEX, "hash", "The transaction hash (differs from txid for witness transactions)"},
100 4 : {RPCResult::Type::NUM, "size", "The serialized transaction size"},
101 4 : {RPCResult::Type::NUM, "vsize", "The virtual transaction size (differs from size for witness transactions)"},
102 4 : {RPCResult::Type::NUM, "weight", "The transaction's weight (between vsize*4-3 and vsize*4)"},
103 4 : {RPCResult::Type::NUM, "version", "The version"},
104 4 : {RPCResult::Type::NUM_TIME, "locktime", "The lock time"},
105 8 : {RPCResult::Type::ARR, "vin", "",
106 8 : {
107 8 : {RPCResult::Type::OBJ, "", "",
108 28 : {
109 4 : {RPCResult::Type::STR_HEX, "coinbase", /*optional=*/true, "The coinbase value (only if coinbase transaction)"},
110 4 : {RPCResult::Type::STR_HEX, "txid", /*optional=*/true, "The transaction id (if not coinbase transaction)"},
111 4 : {RPCResult::Type::NUM, "vout", /*optional=*/true, "The output number (if not coinbase transaction)"},
112 8 : {RPCResult::Type::OBJ, "scriptSig", /*optional=*/true, "The script (if not coinbase transaction)",
113 12 : {
114 4 : {RPCResult::Type::STR, "asm", "Disassembly of the signature script"},
115 4 : {RPCResult::Type::STR_HEX, "hex", "The raw signature script bytes, hex-encoded"},
116 : }},
117 8 : {RPCResult::Type::ARR, "txinwitness", /*optional=*/true, "",
118 8 : {
119 4 : {RPCResult::Type::STR_HEX, "hex", "hex-encoded witness data (if any)"},
120 : }},
121 4 : {RPCResult::Type::NUM, "sequence", "The script sequence number"},
122 : }},
123 : }},
124 8 : {RPCResult::Type::ARR, "vout", "",
125 8 : {
126 8 : {RPCResult::Type::OBJ, "", "",
127 16 : {
128 4 : {RPCResult::Type::STR_AMOUNT, "value", "The value in " + CURRENCY_UNIT},
129 4 : {RPCResult::Type::NUM, "n", "index"},
130 4 : {RPCResult::Type::OBJ, "scriptPubKey", "", ScriptPubKeyDoc()},
131 : }},
132 : }},
133 : };
134 0 : }
135 :
136 4 : static std::vector<RPCArg> CreateTxDoc()
137 : {
138 20 : return {
139 8 : {"inputs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The inputs",
140 8 : {
141 8 : {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "",
142 16 : {
143 4 : {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
144 4 : {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"},
145 4 : {"sequence", RPCArg::Type::NUM, RPCArg::DefaultHint{"depends on the value of the 'replaceable' and 'locktime' arguments"}, "The sequence number"},
146 : },
147 : },
148 : },
149 : },
150 14 : {"outputs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The outputs specified as key-value pairs.\n"
151 6 : "Each key may only appear once, i.e. there can only be one 'data' output, and no address may be duplicated.\n"
152 : "At least one output of either type must be specified.\n"
153 : "For compatibility reasons, a dictionary, which holds the key-value pairs directly, is also\n"
154 : " accepted as second parameter.",
155 12 : {
156 8 : {"", RPCArg::Type::OBJ_USER_KEYS, RPCArg::Optional::OMITTED, "",
157 8 : {
158 4 : {"address", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "A key-value pair. The key (string) is the bitcoin address, the value (float or string) is the amount in " + CURRENCY_UNIT},
159 : },
160 : },
161 8 : {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "",
162 8 : {
163 4 : {"data", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "A key-value pair. The key must be \"data\", the value is hex-encoded data"},
164 : },
165 : },
166 : },
167 12 : RPCArgOptions{.skip_type_check = true}},
168 4 : {"locktime", RPCArg::Type::NUM, RPCArg::Default{0}, "Raw locktime. Non-0 value also locktime-activates inputs"},
169 4 : {"replaceable", RPCArg::Type::BOOL, RPCArg::Default{true}, "Marks this transaction as BIP125-replaceable.\n"
170 : "Allows this transaction to be replaced by a transaction with higher fees. If provided, it is an error if explicit sequence numbers are incompatible."},
171 : };
172 0 : }
173 :
174 : // Update PSBT with information from the mempool, the UTXO set, the txindex, and the provided descriptors.
175 : // Optionally, sign the inputs that we can using information from the descriptors.
176 0 : PartiallySignedTransaction ProcessPSBT(const std::string& psbt_string, const std::any& context, const HidingSigningProvider& provider, int sighash_type, bool finalize)
177 : {
178 : // Unserialize the transactions
179 0 : PartiallySignedTransaction psbtx;
180 0 : std::string error;
181 0 : if (!DecodeBase64PSBT(psbtx, psbt_string, error)) {
182 0 : throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
183 : }
184 :
185 0 : if (g_txindex) g_txindex->BlockUntilSyncedToCurrentChain();
186 0 : const NodeContext& node = EnsureAnyNodeContext(context);
187 :
188 : // If we can't find the corresponding full transaction for all of our inputs,
189 : // this will be used to find just the utxos for the segwit inputs for which
190 : // the full transaction isn't found
191 0 : std::map<COutPoint, Coin> coins;
192 :
193 : // Fetch previous transactions:
194 : // First, look in the txindex and the mempool
195 0 : for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
196 0 : PSBTInput& psbt_input = psbtx.inputs.at(i);
197 0 : const CTxIn& tx_in = psbtx.tx->vin.at(i);
198 :
199 : // The `non_witness_utxo` is the whole previous transaction
200 0 : if (psbt_input.non_witness_utxo) continue;
201 :
202 0 : CTransactionRef tx;
203 :
204 : // Look in the txindex
205 0 : if (g_txindex) {
206 0 : uint256 block_hash;
207 0 : g_txindex->FindTx(tx_in.prevout.hash, block_hash, tx);
208 0 : }
209 : // If we still don't have it look in the mempool
210 0 : if (!tx) {
211 0 : tx = node.mempool->get(tx_in.prevout.hash);
212 0 : }
213 0 : if (tx) {
214 0 : psbt_input.non_witness_utxo = tx;
215 0 : } else {
216 0 : coins[tx_in.prevout]; // Create empty map entry keyed by prevout
217 : }
218 0 : }
219 :
220 : // If we still haven't found all of the inputs, look for the missing ones in the utxo set
221 0 : if (!coins.empty()) {
222 0 : FindCoins(node, coins);
223 0 : for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
224 0 : PSBTInput& input = psbtx.inputs.at(i);
225 :
226 : // If there are still missing utxos, add them if they were found in the utxo set
227 0 : if (!input.non_witness_utxo) {
228 0 : const CTxIn& tx_in = psbtx.tx->vin.at(i);
229 0 : const Coin& coin = coins.at(tx_in.prevout);
230 0 : if (!coin.out.IsNull() && IsSegWitOutput(provider, coin.out.scriptPubKey)) {
231 0 : input.witness_utxo = coin.out;
232 0 : }
233 0 : }
234 0 : }
235 0 : }
236 :
237 0 : const PrecomputedTransactionData& txdata = PrecomputePSBTData(psbtx);
238 :
239 0 : for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
240 0 : if (PSBTInputSigned(psbtx.inputs.at(i))) {
241 0 : continue;
242 : }
243 :
244 : // Update script/keypath information using descriptor data.
245 : // Note that SignPSBTInput does a lot more than just constructing ECDSA signatures.
246 : // We only actually care about those if our signing provider doesn't hide private
247 : // information, as is the case with `descriptorprocesspsbt`
248 0 : SignPSBTInput(provider, psbtx, /*index=*/i, &txdata, sighash_type, /*out_sigdata=*/nullptr, finalize);
249 0 : }
250 :
251 : // Update script/keypath information using descriptor data.
252 0 : for (unsigned int i = 0; i < psbtx.tx->vout.size(); ++i) {
253 0 : UpdatePSBTOutput(provider, psbtx, i);
254 0 : }
255 :
256 0 : RemoveUnnecessaryTransactions(psbtx, /*sighash_type=*/1);
257 :
258 0 : return psbtx;
259 0 : }
260 :
261 2 : static RPCHelpMan getrawtransaction()
262 : {
263 2 : return RPCHelpMan{
264 2 : "getrawtransaction",
265 :
266 2 : "By default, this call only returns a transaction if it is in the mempool. If -txindex is enabled\n"
267 : "and no blockhash argument is passed, it will return the transaction if it is in the mempool or any block.\n"
268 : "If a blockhash argument is passed, it will return the transaction if\n"
269 : "the specified block is available and the transaction is in that block.\n\n"
270 : "Hint: Use gettransaction for wallet transactions.\n\n"
271 :
272 : "If verbosity is 0 or omitted, returns the serialized transaction as a hex-encoded string.\n"
273 : "If verbosity is 1, returns a JSON Object with information about the transaction.\n"
274 : "If verbosity is 2, returns a JSON Object with information about the transaction, including fee and prevout information.",
275 8 : {
276 2 : {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
277 2 : {"verbosity|verbose", RPCArg::Type::NUM, RPCArg::Default{0}, "0 for hex-encoded data, 1 for a JSON object, and 2 for JSON object with fee and prevout",
278 6 : RPCArgOptions{.skip_type_check = true}},
279 2 : {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "The block in which to look for the transaction"},
280 : },
281 8 : {
282 4 : RPCResult{"if verbosity is not set or set to 0",
283 2 : RPCResult::Type::STR, "data", "The serialized transaction as a hex-encoded string for 'txid'"
284 : },
285 4 : RPCResult{"if verbosity is set to 1",
286 2 : RPCResult::Type::OBJ, "", "",
287 2 : Cat<std::vector<RPCResult>>(
288 14 : {
289 2 : {RPCResult::Type::BOOL, "in_active_chain", /*optional=*/true, "Whether specified block is in the active chain or not (only present with explicit \"blockhash\" argument)"},
290 2 : {RPCResult::Type::STR_HEX, "blockhash", /*optional=*/true, "the block hash"},
291 2 : {RPCResult::Type::NUM, "confirmations", /*optional=*/true, "The confirmations"},
292 2 : {RPCResult::Type::NUM_TIME, "blocktime", /*optional=*/true, "The block time expressed in " + UNIX_EPOCH_TIME},
293 2 : {RPCResult::Type::NUM, "time", /*optional=*/true, "Same as \"blocktime\""},
294 2 : {RPCResult::Type::STR_HEX, "hex", "The serialized, hex-encoded data for 'txid'"},
295 : },
296 2 : DecodeTxDoc(/*txid_field_doc=*/"The transaction id (same as provided)")),
297 : },
298 4 : RPCResult{"for verbosity = 2",
299 2 : RPCResult::Type::OBJ, "", "",
300 8 : {
301 2 : {RPCResult::Type::ELISION, "", "Same output as verbosity = 1"},
302 2 : {RPCResult::Type::NUM, "fee", /*optional=*/true, "transaction fee in " + CURRENCY_UNIT + ", omitted if block undo data is not available"},
303 4 : {RPCResult::Type::ARR, "vin", "",
304 4 : {
305 4 : {RPCResult::Type::OBJ, "", "utxo being spent",
306 6 : {
307 2 : {RPCResult::Type::ELISION, "", "Same output as verbosity = 1"},
308 4 : {RPCResult::Type::OBJ, "prevout", /*optional=*/true, "The previous output, omitted if block undo data is not available",
309 10 : {
310 2 : {RPCResult::Type::BOOL, "generated", "Coinbase or not"},
311 2 : {RPCResult::Type::NUM, "height", "The height of the prevout"},
312 2 : {RPCResult::Type::STR_AMOUNT, "value", "The value in " + CURRENCY_UNIT},
313 2 : {RPCResult::Type::OBJ, "scriptPubKey", "", ScriptPubKeyDoc()},
314 : }},
315 : }},
316 : }},
317 : }},
318 : },
319 2 : RPCExamples{
320 2 : HelpExampleCli("getrawtransaction", "\"mytxid\"")
321 2 : + HelpExampleCli("getrawtransaction", "\"mytxid\" 1")
322 2 : + HelpExampleRpc("getrawtransaction", "\"mytxid\", 1")
323 2 : + HelpExampleCli("getrawtransaction", "\"mytxid\" 0 \"myblockhash\"")
324 2 : + HelpExampleCli("getrawtransaction", "\"mytxid\" 1 \"myblockhash\"")
325 2 : + HelpExampleCli("getrawtransaction", "\"mytxid\" 2 \"myblockhash\"")
326 : },
327 2 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
328 : {
329 0 : const NodeContext& node = EnsureAnyNodeContext(request.context);
330 0 : ChainstateManager& chainman = EnsureChainman(node);
331 :
332 0 : uint256 hash = ParseHashV(request.params[0], "parameter 1");
333 0 : const CBlockIndex* blockindex = nullptr;
334 :
335 0 : if (hash == chainman.GetParams().GenesisBlock().hashMerkleRoot) {
336 : // Special exception for the genesis block coinbase transaction
337 0 : throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "The genesis block coinbase is not considered an ordinary transaction and cannot be retrieved");
338 : }
339 :
340 : // Accept either a bool (true) or a num (>=0) to indicate verbosity.
341 0 : int verbosity{0};
342 0 : if (!request.params[1].isNull()) {
343 0 : if (request.params[1].isBool()) {
344 0 : verbosity = request.params[1].get_bool();
345 0 : } else {
346 0 : verbosity = request.params[1].getInt<int>();
347 : }
348 0 : }
349 :
350 0 : if (!request.params[2].isNull()) {
351 0 : LOCK(cs_main);
352 :
353 0 : uint256 blockhash = ParseHashV(request.params[2], "parameter 3");
354 0 : blockindex = chainman.m_blockman.LookupBlockIndex(blockhash);
355 0 : if (!blockindex) {
356 0 : throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block hash not found");
357 : }
358 0 : }
359 :
360 0 : bool f_txindex_ready = false;
361 0 : if (g_txindex && !blockindex) {
362 0 : f_txindex_ready = g_txindex->BlockUntilSyncedToCurrentChain();
363 0 : }
364 :
365 0 : uint256 hash_block;
366 0 : const CTransactionRef tx = GetTransaction(blockindex, node.mempool.get(), hash, hash_block, chainman.m_blockman);
367 0 : if (!tx) {
368 0 : std::string errmsg;
369 0 : if (blockindex) {
370 0 : const bool block_has_data = WITH_LOCK(::cs_main, return blockindex->nStatus & BLOCK_HAVE_DATA);
371 0 : if (!block_has_data) {
372 0 : throw JSONRPCError(RPC_MISC_ERROR, "Block not available");
373 : }
374 0 : errmsg = "No such transaction found in the provided block";
375 0 : } else if (!g_txindex) {
376 0 : errmsg = "No such mempool transaction. Use -txindex or provide a block hash to enable blockchain transaction queries";
377 0 : } else if (!f_txindex_ready) {
378 0 : errmsg = "No such mempool transaction. Blockchain transactions are still in the process of being indexed";
379 0 : } else {
380 0 : errmsg = "No such mempool or blockchain transaction";
381 : }
382 0 : throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, errmsg + ". Use gettransaction for wallet transactions.");
383 0 : }
384 :
385 0 : if (verbosity <= 0) {
386 0 : return EncodeHexTx(*tx, RPCSerializationFlags());
387 : }
388 :
389 0 : UniValue result(UniValue::VOBJ);
390 0 : if (blockindex) {
391 0 : LOCK(cs_main);
392 0 : result.pushKV("in_active_chain", chainman.ActiveChain().Contains(blockindex));
393 0 : }
394 : // If request is verbosity >= 1 but no blockhash was given, then look up the blockindex
395 0 : if (request.params[2].isNull()) {
396 0 : LOCK(cs_main);
397 0 : blockindex = chainman.m_blockman.LookupBlockIndex(hash_block);
398 0 : }
399 0 : if (verbosity == 1) {
400 0 : TxToJSON(*tx, hash_block, result, chainman.ActiveChainstate());
401 0 : return result;
402 : }
403 :
404 0 : CBlockUndo blockUndo;
405 0 : CBlock block;
406 0 : const bool is_block_pruned{WITH_LOCK(cs_main, return chainman.m_blockman.IsBlockPruned(blockindex))};
407 :
408 0 : if (tx->IsCoinBase() ||
409 0 : !blockindex || is_block_pruned ||
410 0 : !(chainman.m_blockman.UndoReadFromDisk(blockUndo, *blockindex) && chainman.m_blockman.ReadBlockFromDisk(block, *blockindex))) {
411 0 : TxToJSON(*tx, hash_block, result, chainman.ActiveChainstate());
412 0 : return result;
413 : }
414 :
415 0 : CTxUndo* undoTX {nullptr};
416 0 : auto it = std::find_if(block.vtx.begin(), block.vtx.end(), [tx](CTransactionRef t){ return *t == *tx; });
417 0 : if (it != block.vtx.end()) {
418 : // -1 as blockundo does not have coinbase tx
419 0 : undoTX = &blockUndo.vtxundo.at(it - block.vtx.begin() - 1);
420 0 : }
421 0 : TxToJSON(*tx, hash_block, result, chainman.ActiveChainstate(), undoTX, TxVerbosity::SHOW_DETAILS_AND_PREVOUT);
422 0 : return result;
423 0 : },
424 : };
425 0 : }
426 :
427 2 : static RPCHelpMan createrawtransaction()
428 : {
429 4 : return RPCHelpMan{"createrawtransaction",
430 2 : "\nCreate a transaction spending the given inputs and creating new outputs.\n"
431 : "Outputs can be addresses or data.\n"
432 : "Returns hex-encoded raw transaction.\n"
433 : "Note that the transaction's inputs are not signed, and\n"
434 : "it is not stored in the wallet or transmitted to the network.\n",
435 2 : CreateTxDoc(),
436 2 : RPCResult{
437 2 : RPCResult::Type::STR_HEX, "transaction", "hex string of the transaction"
438 : },
439 2 : RPCExamples{
440 2 : HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"address\\\":0.01}]\"")
441 2 : + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"")
442 2 : + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"[{\\\"address\\\":0.01}]\"")
443 2 : + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"[{\\\"data\\\":\\\"00010203\\\"}]\"")
444 : },
445 2 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
446 : {
447 0 : std::optional<bool> rbf;
448 0 : if (!request.params[3].isNull()) {
449 0 : rbf = request.params[3].get_bool();
450 0 : }
451 0 : CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], rbf);
452 :
453 0 : return EncodeHexTx(CTransaction(rawTx));
454 0 : },
455 : };
456 0 : }
457 :
458 2 : static RPCHelpMan decoderawtransaction()
459 : {
460 4 : return RPCHelpMan{"decoderawtransaction",
461 2 : "Return a JSON object representing the serialized, hex-encoded transaction.",
462 6 : {
463 2 : {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction hex string"},
464 2 : {"iswitness", RPCArg::Type::BOOL, RPCArg::DefaultHint{"depends on heuristic tests"}, "Whether the transaction hex is a serialized witness transaction.\n"
465 : "If iswitness is not present, heuristic tests will be used in decoding.\n"
466 : "If true, only witness deserialization will be tried.\n"
467 : "If false, only non-witness deserialization will be tried.\n"
468 : "This boolean should reflect whether the transaction has inputs\n"
469 : "(e.g. fully valid, or on-chain transactions), if known by the caller."
470 : },
471 : },
472 2 : RPCResult{
473 2 : RPCResult::Type::OBJ, "", "",
474 2 : DecodeTxDoc(/*txid_field_doc=*/"The transaction id"),
475 : },
476 2 : RPCExamples{
477 2 : HelpExampleCli("decoderawtransaction", "\"hexstring\"")
478 2 : + HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
479 : },
480 2 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
481 : {
482 0 : CMutableTransaction mtx;
483 :
484 0 : bool try_witness = request.params[1].isNull() ? true : request.params[1].get_bool();
485 0 : bool try_no_witness = request.params[1].isNull() ? true : !request.params[1].get_bool();
486 :
487 0 : if (!DecodeHexTx(mtx, request.params[0].get_str(), try_no_witness, try_witness)) {
488 0 : throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
489 : }
490 :
491 0 : UniValue result(UniValue::VOBJ);
492 0 : TxToUniv(CTransaction(std::move(mtx)), /*block_hash=*/uint256(), /*entry=*/result, /*include_hex=*/false);
493 :
494 0 : return result;
495 0 : },
496 : };
497 0 : }
498 :
499 2 : static RPCHelpMan decodescript()
500 : {
501 2 : return RPCHelpMan{
502 2 : "decodescript",
503 2 : "\nDecode a hex-encoded script.\n",
504 4 : {
505 2 : {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded script"},
506 : },
507 2 : RPCResult{
508 2 : RPCResult::Type::OBJ, "", "",
509 14 : {
510 2 : {RPCResult::Type::STR, "asm", "Script public key"},
511 2 : {RPCResult::Type::STR, "desc", "Inferred descriptor for the script"},
512 2 : {RPCResult::Type::STR, "type", "The output type (e.g. " + GetAllOutputTypes() + ")"},
513 2 : {RPCResult::Type::STR, "address", /*optional=*/true, "The Bitcoin address (only if a well-defined address exists)"},
514 4 : {RPCResult::Type::STR, "p2sh", /*optional=*/true,
515 2 : "address of P2SH script wrapping this redeem script (not returned for types that should not be wrapped)"},
516 4 : {RPCResult::Type::OBJ, "segwit", /*optional=*/true,
517 2 : "Result of a witness script public key wrapping this redeem script (not returned for types that should not be wrapped)",
518 14 : {
519 2 : {RPCResult::Type::STR, "asm", "String representation of the script public key"},
520 2 : {RPCResult::Type::STR_HEX, "hex", "Hex string of the script public key"},
521 2 : {RPCResult::Type::STR, "type", "The type of the script public key (e.g. witness_v0_keyhash or witness_v0_scripthash)"},
522 2 : {RPCResult::Type::STR, "address", /*optional=*/true, "The Bitcoin address (only if a well-defined address exists)"},
523 2 : {RPCResult::Type::STR, "desc", "Inferred descriptor for the script"},
524 2 : {RPCResult::Type::STR, "p2sh-segwit", "address of the P2SH script wrapping this witness redeem script"},
525 : }},
526 : },
527 : },
528 2 : RPCExamples{
529 2 : HelpExampleCli("decodescript", "\"hexstring\"")
530 2 : + HelpExampleRpc("decodescript", "\"hexstring\"")
531 : },
532 2 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
533 : {
534 0 : UniValue r(UniValue::VOBJ);
535 0 : CScript script;
536 0 : if (request.params[0].get_str().size() > 0){
537 0 : std::vector<unsigned char> scriptData(ParseHexV(request.params[0], "argument"));
538 0 : script = CScript(scriptData.begin(), scriptData.end());
539 0 : } else {
540 : // Empty scripts are valid
541 : }
542 0 : ScriptToUniv(script, /*out=*/r, /*include_hex=*/false, /*include_address=*/true);
543 :
544 0 : std::vector<std::vector<unsigned char>> solutions_data;
545 0 : const TxoutType which_type{Solver(script, solutions_data)};
546 :
547 0 : const bool can_wrap{[&] {
548 0 : switch (which_type) {
549 : case TxoutType::MULTISIG:
550 : case TxoutType::NONSTANDARD:
551 : case TxoutType::PUBKEY:
552 : case TxoutType::PUBKEYHASH:
553 : case TxoutType::WITNESS_V0_KEYHASH:
554 : case TxoutType::WITNESS_V0_SCRIPTHASH:
555 : // Can be wrapped if the checks below pass
556 0 : break;
557 : case TxoutType::NULL_DATA:
558 : case TxoutType::SCRIPTHASH:
559 : case TxoutType::WITNESS_UNKNOWN:
560 : case TxoutType::WITNESS_V1_TAPROOT:
561 : // Should not be wrapped
562 0 : return false;
563 : } // no default case, so the compiler can warn about missing cases
564 0 : if (!script.HasValidOps() || script.IsUnspendable()) {
565 0 : return false;
566 : }
567 0 : for (CScript::const_iterator it{script.begin()}; it != script.end();) {
568 : opcodetype op;
569 0 : CHECK_NONFATAL(script.GetOp(it, op));
570 0 : if (op == OP_CHECKSIGADD || IsOpSuccess(op)) {
571 0 : return false;
572 : }
573 : }
574 0 : return true;
575 0 : }()};
576 :
577 0 : if (can_wrap) {
578 0 : r.pushKV("p2sh", EncodeDestination(ScriptHash(script)));
579 : // P2SH and witness programs cannot be wrapped in P2WSH, if this script
580 : // is a witness program, don't return addresses for a segwit programs.
581 0 : const bool can_wrap_P2WSH{[&] {
582 0 : switch (which_type) {
583 : case TxoutType::MULTISIG:
584 : case TxoutType::PUBKEY:
585 : // Uncompressed pubkeys cannot be used with segwit checksigs.
586 : // If the script contains an uncompressed pubkey, skip encoding of a segwit program.
587 0 : for (const auto& solution : solutions_data) {
588 0 : if ((solution.size() != 1) && !CPubKey(solution).IsCompressed()) {
589 0 : return false;
590 : }
591 : }
592 0 : return true;
593 : case TxoutType::NONSTANDARD:
594 : case TxoutType::PUBKEYHASH:
595 : // Can be P2WSH wrapped
596 0 : return true;
597 : case TxoutType::NULL_DATA:
598 : case TxoutType::SCRIPTHASH:
599 : case TxoutType::WITNESS_UNKNOWN:
600 : case TxoutType::WITNESS_V0_KEYHASH:
601 : case TxoutType::WITNESS_V0_SCRIPTHASH:
602 : case TxoutType::WITNESS_V1_TAPROOT:
603 : // Should not be wrapped
604 0 : return false;
605 : } // no default case, so the compiler can warn about missing cases
606 0 : NONFATAL_UNREACHABLE();
607 0 : }()};
608 0 : if (can_wrap_P2WSH) {
609 0 : UniValue sr(UniValue::VOBJ);
610 0 : CScript segwitScr;
611 0 : FlatSigningProvider provider;
612 0 : if (which_type == TxoutType::PUBKEY) {
613 0 : segwitScr = GetScriptForDestination(WitnessV0KeyHash(Hash160(solutions_data[0])));
614 0 : } else if (which_type == TxoutType::PUBKEYHASH) {
615 0 : segwitScr = GetScriptForDestination(WitnessV0KeyHash(uint160{solutions_data[0]}));
616 0 : } else {
617 : // Scripts that are not fit for P2WPKH are encoded as P2WSH.
618 0 : provider.scripts[CScriptID(script)] = script;
619 0 : segwitScr = GetScriptForDestination(WitnessV0ScriptHash(script));
620 : }
621 0 : ScriptToUniv(segwitScr, /*out=*/sr, /*include_hex=*/true, /*include_address=*/true, /*provider=*/&provider);
622 0 : sr.pushKV("p2sh-segwit", EncodeDestination(ScriptHash(segwitScr)));
623 0 : r.pushKV("segwit", sr);
624 0 : }
625 0 : }
626 :
627 0 : return r;
628 0 : },
629 : };
630 0 : }
631 :
632 2 : static RPCHelpMan combinerawtransaction()
633 : {
634 4 : return RPCHelpMan{"combinerawtransaction",
635 2 : "\nCombine multiple partially signed transactions into one transaction.\n"
636 : "The combined transaction may be another partially signed transaction or a \n"
637 : "fully signed transaction.",
638 4 : {
639 4 : {"txs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The hex strings of partially signed transactions",
640 4 : {
641 2 : {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "A hex-encoded raw transaction"},
642 : },
643 : },
644 : },
645 2 : RPCResult{
646 2 : RPCResult::Type::STR, "", "The hex-encoded raw transaction with signature(s)"
647 : },
648 2 : RPCExamples{
649 2 : HelpExampleCli("combinerawtransaction", R"('["myhex1", "myhex2", "myhex3"]')")
650 : },
651 2 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
652 : {
653 :
654 0 : UniValue txs = request.params[0].get_array();
655 0 : std::vector<CMutableTransaction> txVariants(txs.size());
656 :
657 0 : for (unsigned int idx = 0; idx < txs.size(); idx++) {
658 0 : if (!DecodeHexTx(txVariants[idx], txs[idx].get_str())) {
659 0 : throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed for tx %d. Make sure the tx has at least one input.", idx));
660 : }
661 0 : }
662 :
663 0 : if (txVariants.empty()) {
664 0 : throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transactions");
665 : }
666 :
667 : // mergedTx will end up with all the signatures; it
668 : // starts as a clone of the rawtx:
669 0 : CMutableTransaction mergedTx(txVariants[0]);
670 :
671 : // Fetch previous transactions (inputs):
672 0 : CCoinsView viewDummy;
673 0 : CCoinsViewCache view(&viewDummy);
674 : {
675 0 : NodeContext& node = EnsureAnyNodeContext(request.context);
676 0 : const CTxMemPool& mempool = EnsureMemPool(node);
677 0 : ChainstateManager& chainman = EnsureChainman(node);
678 0 : LOCK2(cs_main, mempool.cs);
679 0 : CCoinsViewCache &viewChain = chainman.ActiveChainstate().CoinsTip();
680 0 : CCoinsViewMemPool viewMempool(&viewChain, mempool);
681 0 : view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
682 :
683 0 : for (const CTxIn& txin : mergedTx.vin) {
684 0 : view.AccessCoin(txin.prevout); // Load entries from viewChain into view; can fail.
685 : }
686 :
687 0 : view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
688 0 : }
689 :
690 : // Use CTransaction for the constant parts of the
691 : // transaction to avoid rehashing.
692 0 : const CTransaction txConst(mergedTx);
693 : // Sign what we can:
694 0 : for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
695 0 : CTxIn& txin = mergedTx.vin[i];
696 0 : const Coin& coin = view.AccessCoin(txin.prevout);
697 0 : if (coin.IsSpent()) {
698 0 : throw JSONRPCError(RPC_VERIFY_ERROR, "Input not found or already spent");
699 : }
700 0 : SignatureData sigdata;
701 :
702 : // ... and merge in other signatures:
703 0 : for (const CMutableTransaction& txv : txVariants) {
704 0 : if (txv.vin.size() > i) {
705 0 : sigdata.MergeSignatureData(DataFromTransaction(txv, i, coin.out));
706 0 : }
707 : }
708 0 : ProduceSignature(DUMMY_SIGNING_PROVIDER, MutableTransactionSignatureCreator(mergedTx, i, coin.out.nValue, 1), coin.out.scriptPubKey, sigdata);
709 :
710 0 : UpdateInput(txin, sigdata);
711 0 : }
712 :
713 0 : return EncodeHexTx(CTransaction(mergedTx));
714 0 : },
715 : };
716 0 : }
717 :
718 2 : static RPCHelpMan signrawtransactionwithkey()
719 : {
720 4 : return RPCHelpMan{"signrawtransactionwithkey",
721 2 : "\nSign inputs for raw transaction (serialized, hex-encoded).\n"
722 : "The second argument is an array of base58-encoded private\n"
723 : "keys that will be the only keys used to sign the transaction.\n"
724 : "The third optional argument (may be null) is an array of previous transaction outputs that\n"
725 : "this transaction depends on but may not yet be in the block chain.\n",
726 10 : {
727 2 : {"hexstring", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction hex string"},
728 4 : {"privkeys", RPCArg::Type::ARR, RPCArg::Optional::NO, "The base58-encoded private keys for signing",
729 4 : {
730 2 : {"privatekey", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "private key in base58-encoding"},
731 : },
732 : },
733 4 : {"prevtxs", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "The previous dependent transaction outputs",
734 4 : {
735 4 : {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "",
736 14 : {
737 2 : {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
738 2 : {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"},
739 2 : {"scriptPubKey", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "script key"},
740 2 : {"redeemScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2SH) redeem script"},
741 2 : {"witnessScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2WSH or P2SH-P2WSH) witness script"},
742 2 : {"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::OMITTED, "(required for Segwit inputs) the amount spent"},
743 : },
744 : },
745 : },
746 : },
747 2 : {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"DEFAULT for Taproot, ALL otherwise"}, "The signature hash type. Must be one of:\n"
748 : " \"DEFAULT\"\n"
749 : " \"ALL\"\n"
750 : " \"NONE\"\n"
751 : " \"SINGLE\"\n"
752 : " \"ALL|ANYONECANPAY\"\n"
753 : " \"NONE|ANYONECANPAY\"\n"
754 : " \"SINGLE|ANYONECANPAY\"\n"
755 : },
756 : },
757 2 : RPCResult{
758 2 : RPCResult::Type::OBJ, "", "",
759 8 : {
760 2 : {RPCResult::Type::STR_HEX, "hex", "The hex-encoded raw transaction with signature(s)"},
761 2 : {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"},
762 4 : {RPCResult::Type::ARR, "errors", /*optional=*/true, "Script verification errors (if there are any)",
763 4 : {
764 4 : {RPCResult::Type::OBJ, "", "",
765 14 : {
766 2 : {RPCResult::Type::STR_HEX, "txid", "The hash of the referenced, previous transaction"},
767 2 : {RPCResult::Type::NUM, "vout", "The index of the output to spent and used as input"},
768 4 : {RPCResult::Type::ARR, "witness", "",
769 4 : {
770 2 : {RPCResult::Type::STR_HEX, "witness", ""},
771 : }},
772 2 : {RPCResult::Type::STR_HEX, "scriptSig", "The hex-encoded signature script"},
773 2 : {RPCResult::Type::NUM, "sequence", "Script sequence number"},
774 2 : {RPCResult::Type::STR, "error", "Verification or signing error related to the input"},
775 : }},
776 : }},
777 : }
778 : },
779 2 : RPCExamples{
780 2 : HelpExampleCli("signrawtransactionwithkey", "\"myhex\" \"[\\\"key1\\\",\\\"key2\\\"]\"")
781 2 : + HelpExampleRpc("signrawtransactionwithkey", "\"myhex\", \"[\\\"key1\\\",\\\"key2\\\"]\"")
782 : },
783 2 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
784 : {
785 0 : CMutableTransaction mtx;
786 0 : if (!DecodeHexTx(mtx, request.params[0].get_str())) {
787 0 : throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input.");
788 : }
789 :
790 0 : FillableSigningProvider keystore;
791 0 : const UniValue& keys = request.params[1].get_array();
792 0 : for (unsigned int idx = 0; idx < keys.size(); ++idx) {
793 0 : UniValue k = keys[idx];
794 0 : CKey key = DecodeSecret(k.get_str());
795 0 : if (!key.IsValid()) {
796 0 : throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
797 : }
798 0 : keystore.AddKey(key);
799 0 : }
800 :
801 : // Fetch previous transactions (inputs):
802 0 : std::map<COutPoint, Coin> coins;
803 0 : for (const CTxIn& txin : mtx.vin) {
804 0 : coins[txin.prevout]; // Create empty map entry keyed by prevout.
805 : }
806 0 : NodeContext& node = EnsureAnyNodeContext(request.context);
807 0 : FindCoins(node, coins);
808 :
809 : // Parse the prevtxs array
810 0 : ParsePrevouts(request.params[2], &keystore, coins);
811 :
812 0 : UniValue result(UniValue::VOBJ);
813 0 : SignTransaction(mtx, &keystore, coins, request.params[3], result);
814 0 : return result;
815 0 : },
816 : };
817 0 : }
818 :
819 2 : const RPCResult decodepsbt_inputs{
820 2 : RPCResult::Type::ARR, "inputs", "",
821 4 : {
822 4 : {RPCResult::Type::OBJ, "", "",
823 44 : {
824 4 : {RPCResult::Type::OBJ, "non_witness_utxo", /*optional=*/true, "Decoded network transaction for non-witness UTXOs",
825 4 : {
826 2 : {RPCResult::Type::ELISION, "",""},
827 : }},
828 4 : {RPCResult::Type::OBJ, "witness_utxo", /*optional=*/true, "Transaction output for witness UTXOs",
829 6 : {
830 2 : {RPCResult::Type::NUM, "amount", "The value in " + CURRENCY_UNIT},
831 4 : {RPCResult::Type::OBJ, "scriptPubKey", "",
832 12 : {
833 2 : {RPCResult::Type::STR, "asm", "Disassembly of the public key script"},
834 2 : {RPCResult::Type::STR, "desc", "Inferred descriptor for the output"},
835 2 : {RPCResult::Type::STR_HEX, "hex", "The raw public key script bytes, hex-encoded"},
836 2 : {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
837 2 : {RPCResult::Type::STR, "address", /*optional=*/true, "The Bitcoin address (only if a well-defined address exists)"},
838 : }},
839 : }},
840 4 : {RPCResult::Type::OBJ_DYN, "partial_signatures", /*optional=*/true, "",
841 4 : {
842 2 : {RPCResult::Type::STR, "pubkey", "The public key and signature that corresponds to it."},
843 : }},
844 2 : {RPCResult::Type::STR, "sighash", /*optional=*/true, "The sighash type to be used"},
845 4 : {RPCResult::Type::OBJ, "redeem_script", /*optional=*/true, "",
846 8 : {
847 2 : {RPCResult::Type::STR, "asm", "Disassembly of the redeem script"},
848 2 : {RPCResult::Type::STR_HEX, "hex", "The raw redeem script bytes, hex-encoded"},
849 2 : {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
850 : }},
851 4 : {RPCResult::Type::OBJ, "witness_script", /*optional=*/true, "",
852 8 : {
853 2 : {RPCResult::Type::STR, "asm", "Disassembly of the witness script"},
854 2 : {RPCResult::Type::STR_HEX, "hex", "The raw witness script bytes, hex-encoded"},
855 2 : {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
856 : }},
857 4 : {RPCResult::Type::ARR, "bip32_derivs", /*optional=*/true, "",
858 4 : {
859 4 : {RPCResult::Type::OBJ, "", "",
860 8 : {
861 2 : {RPCResult::Type::STR, "pubkey", "The public key with the derivation path as the value."},
862 2 : {RPCResult::Type::STR, "master_fingerprint", "The fingerprint of the master key"},
863 2 : {RPCResult::Type::STR, "path", "The path"},
864 : }},
865 : }},
866 4 : {RPCResult::Type::OBJ, "final_scriptSig", /*optional=*/true, "",
867 6 : {
868 2 : {RPCResult::Type::STR, "asm", "Disassembly of the final signature script"},
869 2 : {RPCResult::Type::STR_HEX, "hex", "The raw final signature script bytes, hex-encoded"},
870 : }},
871 4 : {RPCResult::Type::ARR, "final_scriptwitness", /*optional=*/true, "",
872 4 : {
873 2 : {RPCResult::Type::STR_HEX, "", "hex-encoded witness data (if any)"},
874 : }},
875 4 : {RPCResult::Type::OBJ_DYN, "ripemd160_preimages", /*optional=*/ true, "",
876 4 : {
877 2 : {RPCResult::Type::STR, "hash", "The hash and preimage that corresponds to it."},
878 : }},
879 4 : {RPCResult::Type::OBJ_DYN, "sha256_preimages", /*optional=*/ true, "",
880 4 : {
881 2 : {RPCResult::Type::STR, "hash", "The hash and preimage that corresponds to it."},
882 : }},
883 4 : {RPCResult::Type::OBJ_DYN, "hash160_preimages", /*optional=*/ true, "",
884 4 : {
885 2 : {RPCResult::Type::STR, "hash", "The hash and preimage that corresponds to it."},
886 : }},
887 4 : {RPCResult::Type::OBJ_DYN, "hash256_preimages", /*optional=*/ true, "",
888 4 : {
889 2 : {RPCResult::Type::STR, "hash", "The hash and preimage that corresponds to it."},
890 : }},
891 2 : {RPCResult::Type::STR_HEX, "taproot_key_path_sig", /*optional=*/ true, "hex-encoded signature for the Taproot key path spend"},
892 4 : {RPCResult::Type::ARR, "taproot_script_path_sigs", /*optional=*/ true, "",
893 4 : {
894 4 : {RPCResult::Type::OBJ, "signature", /*optional=*/ true, "The signature for the pubkey and leaf hash combination",
895 8 : {
896 2 : {RPCResult::Type::STR, "pubkey", "The x-only pubkey for this signature"},
897 2 : {RPCResult::Type::STR, "leaf_hash", "The leaf hash for this signature"},
898 2 : {RPCResult::Type::STR, "sig", "The signature itself"},
899 : }},
900 : }},
901 4 : {RPCResult::Type::ARR, "taproot_scripts", /*optional=*/ true, "",
902 4 : {
903 4 : {RPCResult::Type::OBJ, "", "",
904 8 : {
905 2 : {RPCResult::Type::STR_HEX, "script", "A leaf script"},
906 2 : {RPCResult::Type::NUM, "leaf_ver", "The version number for the leaf script"},
907 4 : {RPCResult::Type::ARR, "control_blocks", "The control blocks for this script",
908 4 : {
909 2 : {RPCResult::Type::STR_HEX, "control_block", "A hex-encoded control block for this script"},
910 : }},
911 : }},
912 : }},
913 4 : {RPCResult::Type::ARR, "taproot_bip32_derivs", /*optional=*/ true, "",
914 4 : {
915 4 : {RPCResult::Type::OBJ, "", "",
916 10 : {
917 2 : {RPCResult::Type::STR, "pubkey", "The x-only public key this path corresponds to"},
918 2 : {RPCResult::Type::STR, "master_fingerprint", "The fingerprint of the master key"},
919 2 : {RPCResult::Type::STR, "path", "The path"},
920 4 : {RPCResult::Type::ARR, "leaf_hashes", "The hashes of the leaves this pubkey appears in",
921 4 : {
922 2 : {RPCResult::Type::STR_HEX, "hash", "The hash of a leaf this pubkey appears in"},
923 : }},
924 : }},
925 : }},
926 2 : {RPCResult::Type::STR_HEX, "taproot_internal_key", /*optional=*/ true, "The hex-encoded Taproot x-only internal key"},
927 2 : {RPCResult::Type::STR_HEX, "taproot_merkle_root", /*optional=*/ true, "The hex-encoded Taproot merkle root"},
928 4 : {RPCResult::Type::OBJ_DYN, "unknown", /*optional=*/ true, "The unknown input fields",
929 4 : {
930 2 : {RPCResult::Type::STR_HEX, "key", "(key-value pair) An unknown key-value pair"},
931 : }},
932 4 : {RPCResult::Type::ARR, "proprietary", /*optional=*/true, "The input proprietary map",
933 4 : {
934 4 : {RPCResult::Type::OBJ, "", "",
935 10 : {
936 2 : {RPCResult::Type::STR_HEX, "identifier", "The hex string for the proprietary identifier"},
937 2 : {RPCResult::Type::NUM, "subtype", "The number for the subtype"},
938 2 : {RPCResult::Type::STR_HEX, "key", "The hex for the key"},
939 2 : {RPCResult::Type::STR_HEX, "value", "The hex for the value"},
940 : }},
941 : }},
942 : }},
943 : }
944 : };
945 :
946 2 : const RPCResult decodepsbt_outputs{
947 2 : RPCResult::Type::ARR, "outputs", "",
948 4 : {
949 4 : {RPCResult::Type::OBJ, "", "",
950 18 : {
951 4 : {RPCResult::Type::OBJ, "redeem_script", /*optional=*/true, "",
952 8 : {
953 2 : {RPCResult::Type::STR, "asm", "Disassembly of the redeem script"},
954 2 : {RPCResult::Type::STR_HEX, "hex", "The raw redeem script bytes, hex-encoded"},
955 2 : {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
956 : }},
957 4 : {RPCResult::Type::OBJ, "witness_script", /*optional=*/true, "",
958 8 : {
959 2 : {RPCResult::Type::STR, "asm", "Disassembly of the witness script"},
960 2 : {RPCResult::Type::STR_HEX, "hex", "The raw witness script bytes, hex-encoded"},
961 2 : {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
962 : }},
963 4 : {RPCResult::Type::ARR, "bip32_derivs", /*optional=*/true, "",
964 4 : {
965 4 : {RPCResult::Type::OBJ, "", "",
966 8 : {
967 2 : {RPCResult::Type::STR, "pubkey", "The public key this path corresponds to"},
968 2 : {RPCResult::Type::STR, "master_fingerprint", "The fingerprint of the master key"},
969 2 : {RPCResult::Type::STR, "path", "The path"},
970 : }},
971 : }},
972 2 : {RPCResult::Type::STR_HEX, "taproot_internal_key", /*optional=*/ true, "The hex-encoded Taproot x-only internal key"},
973 4 : {RPCResult::Type::ARR, "taproot_tree", /*optional=*/ true, "The tuples that make up the Taproot tree, in depth first search order",
974 4 : {
975 4 : {RPCResult::Type::OBJ, "tuple", /*optional=*/ true, "A single leaf script in the taproot tree",
976 8 : {
977 2 : {RPCResult::Type::NUM, "depth", "The depth of this element in the tree"},
978 2 : {RPCResult::Type::NUM, "leaf_ver", "The version of this leaf"},
979 2 : {RPCResult::Type::STR, "script", "The hex-encoded script itself"},
980 : }},
981 : }},
982 4 : {RPCResult::Type::ARR, "taproot_bip32_derivs", /*optional=*/ true, "",
983 4 : {
984 4 : {RPCResult::Type::OBJ, "", "",
985 10 : {
986 2 : {RPCResult::Type::STR, "pubkey", "The x-only public key this path corresponds to"},
987 2 : {RPCResult::Type::STR, "master_fingerprint", "The fingerprint of the master key"},
988 2 : {RPCResult::Type::STR, "path", "The path"},
989 4 : {RPCResult::Type::ARR, "leaf_hashes", "The hashes of the leaves this pubkey appears in",
990 4 : {
991 2 : {RPCResult::Type::STR_HEX, "hash", "The hash of a leaf this pubkey appears in"},
992 : }},
993 : }},
994 : }},
995 4 : {RPCResult::Type::OBJ_DYN, "unknown", /*optional=*/true, "The unknown output fields",
996 4 : {
997 2 : {RPCResult::Type::STR_HEX, "key", "(key-value pair) An unknown key-value pair"},
998 : }},
999 4 : {RPCResult::Type::ARR, "proprietary", /*optional=*/true, "The output proprietary map",
1000 4 : {
1001 4 : {RPCResult::Type::OBJ, "", "",
1002 10 : {
1003 2 : {RPCResult::Type::STR_HEX, "identifier", "The hex string for the proprietary identifier"},
1004 2 : {RPCResult::Type::NUM, "subtype", "The number for the subtype"},
1005 2 : {RPCResult::Type::STR_HEX, "key", "The hex for the key"},
1006 2 : {RPCResult::Type::STR_HEX, "value", "The hex for the value"},
1007 : }},
1008 : }},
1009 : }},
1010 : }
1011 : };
1012 :
1013 2 : static RPCHelpMan decodepsbt()
1014 : {
1015 2 : return RPCHelpMan{
1016 2 : "decodepsbt",
1017 2 : "Return a JSON object representing the serialized, base64-encoded partially signed Bitcoin transaction.",
1018 4 : {
1019 2 : {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "The PSBT base64 string"},
1020 : },
1021 2 : RPCResult{
1022 2 : RPCResult::Type::OBJ, "", "",
1023 14 : {
1024 4 : {RPCResult::Type::OBJ, "tx", "The decoded network-serialized unsigned transaction.",
1025 4 : {
1026 2 : {RPCResult::Type::ELISION, "", "The layout is the same as the output of decoderawtransaction."},
1027 : }},
1028 4 : {RPCResult::Type::ARR, "global_xpubs", "",
1029 4 : {
1030 4 : {RPCResult::Type::OBJ, "", "",
1031 8 : {
1032 2 : {RPCResult::Type::STR, "xpub", "The extended public key this path corresponds to"},
1033 2 : {RPCResult::Type::STR_HEX, "master_fingerprint", "The fingerprint of the master key"},
1034 2 : {RPCResult::Type::STR, "path", "The path"},
1035 : }},
1036 : }},
1037 2 : {RPCResult::Type::NUM, "psbt_version", "The PSBT version number. Not to be confused with the unsigned transaction version"},
1038 4 : {RPCResult::Type::ARR, "proprietary", "The global proprietary map",
1039 4 : {
1040 4 : {RPCResult::Type::OBJ, "", "",
1041 10 : {
1042 2 : {RPCResult::Type::STR_HEX, "identifier", "The hex string for the proprietary identifier"},
1043 2 : {RPCResult::Type::NUM, "subtype", "The number for the subtype"},
1044 2 : {RPCResult::Type::STR_HEX, "key", "The hex for the key"},
1045 2 : {RPCResult::Type::STR_HEX, "value", "The hex for the value"},
1046 : }},
1047 : }},
1048 4 : {RPCResult::Type::OBJ_DYN, "unknown", "The unknown global fields",
1049 4 : {
1050 2 : {RPCResult::Type::STR_HEX, "key", "(key-value pair) An unknown key-value pair"},
1051 : }},
1052 2 : decodepsbt_inputs,
1053 2 : decodepsbt_outputs,
1054 2 : {RPCResult::Type::STR_AMOUNT, "fee", /*optional=*/true, "The transaction fee paid if all UTXOs slots in the PSBT have been filled."},
1055 : }
1056 : },
1057 2 : RPCExamples{
1058 2 : HelpExampleCli("decodepsbt", "\"psbt\"")
1059 : },
1060 2 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1061 : {
1062 : // Unserialize the transactions
1063 0 : PartiallySignedTransaction psbtx;
1064 0 : std::string error;
1065 0 : if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
1066 0 : throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
1067 : }
1068 :
1069 0 : UniValue result(UniValue::VOBJ);
1070 :
1071 : // Add the decoded tx
1072 0 : UniValue tx_univ(UniValue::VOBJ);
1073 0 : TxToUniv(CTransaction(*psbtx.tx), /*block_hash=*/uint256(), /*entry=*/tx_univ, /*include_hex=*/false);
1074 0 : result.pushKV("tx", tx_univ);
1075 :
1076 : // Add the global xpubs
1077 0 : UniValue global_xpubs(UniValue::VARR);
1078 0 : for (std::pair<KeyOriginInfo, std::set<CExtPubKey>> xpub_pair : psbtx.m_xpubs) {
1079 0 : for (auto& xpub : xpub_pair.second) {
1080 0 : std::vector<unsigned char> ser_xpub;
1081 0 : ser_xpub.assign(BIP32_EXTKEY_WITH_VERSION_SIZE, 0);
1082 0 : xpub.EncodeWithVersion(ser_xpub.data());
1083 :
1084 0 : UniValue keypath(UniValue::VOBJ);
1085 0 : keypath.pushKV("xpub", EncodeBase58Check(ser_xpub));
1086 0 : keypath.pushKV("master_fingerprint", HexStr(Span<unsigned char>(xpub_pair.first.fingerprint, xpub_pair.first.fingerprint + 4)));
1087 0 : keypath.pushKV("path", WriteHDKeypath(xpub_pair.first.path));
1088 0 : global_xpubs.push_back(keypath);
1089 0 : }
1090 0 : }
1091 0 : result.pushKV("global_xpubs", global_xpubs);
1092 :
1093 : // PSBT version
1094 0 : result.pushKV("psbt_version", static_cast<uint64_t>(psbtx.GetVersion()));
1095 :
1096 : // Proprietary
1097 0 : UniValue proprietary(UniValue::VARR);
1098 0 : for (const auto& entry : psbtx.m_proprietary) {
1099 0 : UniValue this_prop(UniValue::VOBJ);
1100 0 : this_prop.pushKV("identifier", HexStr(entry.identifier));
1101 0 : this_prop.pushKV("subtype", entry.subtype);
1102 0 : this_prop.pushKV("key", HexStr(entry.key));
1103 0 : this_prop.pushKV("value", HexStr(entry.value));
1104 0 : proprietary.push_back(this_prop);
1105 0 : }
1106 0 : result.pushKV("proprietary", proprietary);
1107 :
1108 : // Unknown data
1109 0 : UniValue unknowns(UniValue::VOBJ);
1110 0 : for (auto entry : psbtx.unknown) {
1111 0 : unknowns.pushKV(HexStr(entry.first), HexStr(entry.second));
1112 0 : }
1113 0 : result.pushKV("unknown", unknowns);
1114 :
1115 : // inputs
1116 0 : CAmount total_in = 0;
1117 0 : bool have_all_utxos = true;
1118 0 : UniValue inputs(UniValue::VARR);
1119 0 : for (unsigned int i = 0; i < psbtx.inputs.size(); ++i) {
1120 0 : const PSBTInput& input = psbtx.inputs[i];
1121 0 : UniValue in(UniValue::VOBJ);
1122 : // UTXOs
1123 0 : bool have_a_utxo = false;
1124 0 : CTxOut txout;
1125 0 : if (!input.witness_utxo.IsNull()) {
1126 0 : txout = input.witness_utxo;
1127 :
1128 0 : UniValue o(UniValue::VOBJ);
1129 0 : ScriptToUniv(txout.scriptPubKey, /*out=*/o, /*include_hex=*/true, /*include_address=*/true);
1130 :
1131 0 : UniValue out(UniValue::VOBJ);
1132 0 : out.pushKV("amount", ValueFromAmount(txout.nValue));
1133 0 : out.pushKV("scriptPubKey", o);
1134 :
1135 0 : in.pushKV("witness_utxo", out);
1136 :
1137 0 : have_a_utxo = true;
1138 0 : }
1139 0 : if (input.non_witness_utxo) {
1140 0 : txout = input.non_witness_utxo->vout[psbtx.tx->vin[i].prevout.n];
1141 :
1142 0 : UniValue non_wit(UniValue::VOBJ);
1143 0 : TxToUniv(*input.non_witness_utxo, /*block_hash=*/uint256(), /*entry=*/non_wit, /*include_hex=*/false);
1144 0 : in.pushKV("non_witness_utxo", non_wit);
1145 :
1146 0 : have_a_utxo = true;
1147 0 : }
1148 0 : if (have_a_utxo) {
1149 0 : if (MoneyRange(txout.nValue) && MoneyRange(total_in + txout.nValue)) {
1150 0 : total_in += txout.nValue;
1151 0 : } else {
1152 : // Hack to just not show fee later
1153 0 : have_all_utxos = false;
1154 : }
1155 0 : } else {
1156 0 : have_all_utxos = false;
1157 : }
1158 :
1159 : // Partial sigs
1160 0 : if (!input.partial_sigs.empty()) {
1161 0 : UniValue partial_sigs(UniValue::VOBJ);
1162 0 : for (const auto& sig : input.partial_sigs) {
1163 0 : partial_sigs.pushKV(HexStr(sig.second.first), HexStr(sig.second.second));
1164 : }
1165 0 : in.pushKV("partial_signatures", partial_sigs);
1166 0 : }
1167 :
1168 : // Sighash
1169 0 : if (input.sighash_type != std::nullopt) {
1170 0 : in.pushKV("sighash", SighashToStr((unsigned char)*input.sighash_type));
1171 0 : }
1172 :
1173 : // Redeem script and witness script
1174 0 : if (!input.redeem_script.empty()) {
1175 0 : UniValue r(UniValue::VOBJ);
1176 0 : ScriptToUniv(input.redeem_script, /*out=*/r);
1177 0 : in.pushKV("redeem_script", r);
1178 0 : }
1179 0 : if (!input.witness_script.empty()) {
1180 0 : UniValue r(UniValue::VOBJ);
1181 0 : ScriptToUniv(input.witness_script, /*out=*/r);
1182 0 : in.pushKV("witness_script", r);
1183 0 : }
1184 :
1185 : // keypaths
1186 0 : if (!input.hd_keypaths.empty()) {
1187 0 : UniValue keypaths(UniValue::VARR);
1188 0 : for (auto entry : input.hd_keypaths) {
1189 0 : UniValue keypath(UniValue::VOBJ);
1190 0 : keypath.pushKV("pubkey", HexStr(entry.first));
1191 :
1192 0 : keypath.pushKV("master_fingerprint", strprintf("%08x", ReadBE32(entry.second.fingerprint)));
1193 0 : keypath.pushKV("path", WriteHDKeypath(entry.second.path));
1194 0 : keypaths.push_back(keypath);
1195 0 : }
1196 0 : in.pushKV("bip32_derivs", keypaths);
1197 0 : }
1198 :
1199 : // Final scriptSig and scriptwitness
1200 0 : if (!input.final_script_sig.empty()) {
1201 0 : UniValue scriptsig(UniValue::VOBJ);
1202 0 : scriptsig.pushKV("asm", ScriptToAsmStr(input.final_script_sig, true));
1203 0 : scriptsig.pushKV("hex", HexStr(input.final_script_sig));
1204 0 : in.pushKV("final_scriptSig", scriptsig);
1205 0 : }
1206 0 : if (!input.final_script_witness.IsNull()) {
1207 0 : UniValue txinwitness(UniValue::VARR);
1208 0 : for (const auto& item : input.final_script_witness.stack) {
1209 0 : txinwitness.push_back(HexStr(item));
1210 : }
1211 0 : in.pushKV("final_scriptwitness", txinwitness);
1212 0 : }
1213 :
1214 : // Ripemd160 hash preimages
1215 0 : if (!input.ripemd160_preimages.empty()) {
1216 0 : UniValue ripemd160_preimages(UniValue::VOBJ);
1217 0 : for (const auto& [hash, preimage] : input.ripemd160_preimages) {
1218 0 : ripemd160_preimages.pushKV(HexStr(hash), HexStr(preimage));
1219 : }
1220 0 : in.pushKV("ripemd160_preimages", ripemd160_preimages);
1221 0 : }
1222 :
1223 : // Sha256 hash preimages
1224 0 : if (!input.sha256_preimages.empty()) {
1225 0 : UniValue sha256_preimages(UniValue::VOBJ);
1226 0 : for (const auto& [hash, preimage] : input.sha256_preimages) {
1227 0 : sha256_preimages.pushKV(HexStr(hash), HexStr(preimage));
1228 : }
1229 0 : in.pushKV("sha256_preimages", sha256_preimages);
1230 0 : }
1231 :
1232 : // Hash160 hash preimages
1233 0 : if (!input.hash160_preimages.empty()) {
1234 0 : UniValue hash160_preimages(UniValue::VOBJ);
1235 0 : for (const auto& [hash, preimage] : input.hash160_preimages) {
1236 0 : hash160_preimages.pushKV(HexStr(hash), HexStr(preimage));
1237 : }
1238 0 : in.pushKV("hash160_preimages", hash160_preimages);
1239 0 : }
1240 :
1241 : // Hash256 hash preimages
1242 0 : if (!input.hash256_preimages.empty()) {
1243 0 : UniValue hash256_preimages(UniValue::VOBJ);
1244 0 : for (const auto& [hash, preimage] : input.hash256_preimages) {
1245 0 : hash256_preimages.pushKV(HexStr(hash), HexStr(preimage));
1246 : }
1247 0 : in.pushKV("hash256_preimages", hash256_preimages);
1248 0 : }
1249 :
1250 : // Taproot key path signature
1251 0 : if (!input.m_tap_key_sig.empty()) {
1252 0 : in.pushKV("taproot_key_path_sig", HexStr(input.m_tap_key_sig));
1253 0 : }
1254 :
1255 : // Taproot script path signatures
1256 0 : if (!input.m_tap_script_sigs.empty()) {
1257 0 : UniValue script_sigs(UniValue::VARR);
1258 0 : for (const auto& [pubkey_leaf, sig] : input.m_tap_script_sigs) {
1259 0 : const auto& [xonly, leaf_hash] = pubkey_leaf;
1260 0 : UniValue sigobj(UniValue::VOBJ);
1261 0 : sigobj.pushKV("pubkey", HexStr(xonly));
1262 0 : sigobj.pushKV("leaf_hash", HexStr(leaf_hash));
1263 0 : sigobj.pushKV("sig", HexStr(sig));
1264 0 : script_sigs.push_back(sigobj);
1265 0 : }
1266 0 : in.pushKV("taproot_script_path_sigs", script_sigs);
1267 0 : }
1268 :
1269 : // Taproot leaf scripts
1270 0 : if (!input.m_tap_scripts.empty()) {
1271 0 : UniValue tap_scripts(UniValue::VARR);
1272 0 : for (const auto& [leaf, control_blocks] : input.m_tap_scripts) {
1273 0 : const auto& [script, leaf_ver] = leaf;
1274 0 : UniValue script_info(UniValue::VOBJ);
1275 0 : script_info.pushKV("script", HexStr(script));
1276 0 : script_info.pushKV("leaf_ver", leaf_ver);
1277 0 : UniValue control_blocks_univ(UniValue::VARR);
1278 0 : for (const auto& control_block : control_blocks) {
1279 0 : control_blocks_univ.push_back(HexStr(control_block));
1280 : }
1281 0 : script_info.pushKV("control_blocks", control_blocks_univ);
1282 0 : tap_scripts.push_back(script_info);
1283 0 : }
1284 0 : in.pushKV("taproot_scripts", tap_scripts);
1285 0 : }
1286 :
1287 : // Taproot bip32 keypaths
1288 0 : if (!input.m_tap_bip32_paths.empty()) {
1289 0 : UniValue keypaths(UniValue::VARR);
1290 0 : for (const auto& [xonly, leaf_origin] : input.m_tap_bip32_paths) {
1291 0 : const auto& [leaf_hashes, origin] = leaf_origin;
1292 0 : UniValue path_obj(UniValue::VOBJ);
1293 0 : path_obj.pushKV("pubkey", HexStr(xonly));
1294 0 : path_obj.pushKV("master_fingerprint", strprintf("%08x", ReadBE32(origin.fingerprint)));
1295 0 : path_obj.pushKV("path", WriteHDKeypath(origin.path));
1296 0 : UniValue leaf_hashes_arr(UniValue::VARR);
1297 0 : for (const auto& leaf_hash : leaf_hashes) {
1298 0 : leaf_hashes_arr.push_back(HexStr(leaf_hash));
1299 : }
1300 0 : path_obj.pushKV("leaf_hashes", leaf_hashes_arr);
1301 0 : keypaths.push_back(path_obj);
1302 0 : }
1303 0 : in.pushKV("taproot_bip32_derivs", keypaths);
1304 0 : }
1305 :
1306 : // Taproot internal key
1307 0 : if (!input.m_tap_internal_key.IsNull()) {
1308 0 : in.pushKV("taproot_internal_key", HexStr(input.m_tap_internal_key));
1309 0 : }
1310 :
1311 : // Write taproot merkle root
1312 0 : if (!input.m_tap_merkle_root.IsNull()) {
1313 0 : in.pushKV("taproot_merkle_root", HexStr(input.m_tap_merkle_root));
1314 0 : }
1315 :
1316 : // Proprietary
1317 0 : if (!input.m_proprietary.empty()) {
1318 0 : UniValue proprietary(UniValue::VARR);
1319 0 : for (const auto& entry : input.m_proprietary) {
1320 0 : UniValue this_prop(UniValue::VOBJ);
1321 0 : this_prop.pushKV("identifier", HexStr(entry.identifier));
1322 0 : this_prop.pushKV("subtype", entry.subtype);
1323 0 : this_prop.pushKV("key", HexStr(entry.key));
1324 0 : this_prop.pushKV("value", HexStr(entry.value));
1325 0 : proprietary.push_back(this_prop);
1326 0 : }
1327 0 : in.pushKV("proprietary", proprietary);
1328 0 : }
1329 :
1330 : // Unknown data
1331 0 : if (input.unknown.size() > 0) {
1332 0 : UniValue unknowns(UniValue::VOBJ);
1333 0 : for (auto entry : input.unknown) {
1334 0 : unknowns.pushKV(HexStr(entry.first), HexStr(entry.second));
1335 0 : }
1336 0 : in.pushKV("unknown", unknowns);
1337 0 : }
1338 :
1339 0 : inputs.push_back(in);
1340 0 : }
1341 0 : result.pushKV("inputs", inputs);
1342 :
1343 : // outputs
1344 0 : CAmount output_value = 0;
1345 0 : UniValue outputs(UniValue::VARR);
1346 0 : for (unsigned int i = 0; i < psbtx.outputs.size(); ++i) {
1347 0 : const PSBTOutput& output = psbtx.outputs[i];
1348 0 : UniValue out(UniValue::VOBJ);
1349 : // Redeem script and witness script
1350 0 : if (!output.redeem_script.empty()) {
1351 0 : UniValue r(UniValue::VOBJ);
1352 0 : ScriptToUniv(output.redeem_script, /*out=*/r);
1353 0 : out.pushKV("redeem_script", r);
1354 0 : }
1355 0 : if (!output.witness_script.empty()) {
1356 0 : UniValue r(UniValue::VOBJ);
1357 0 : ScriptToUniv(output.witness_script, /*out=*/r);
1358 0 : out.pushKV("witness_script", r);
1359 0 : }
1360 :
1361 : // keypaths
1362 0 : if (!output.hd_keypaths.empty()) {
1363 0 : UniValue keypaths(UniValue::VARR);
1364 0 : for (auto entry : output.hd_keypaths) {
1365 0 : UniValue keypath(UniValue::VOBJ);
1366 0 : keypath.pushKV("pubkey", HexStr(entry.first));
1367 0 : keypath.pushKV("master_fingerprint", strprintf("%08x", ReadBE32(entry.second.fingerprint)));
1368 0 : keypath.pushKV("path", WriteHDKeypath(entry.second.path));
1369 0 : keypaths.push_back(keypath);
1370 0 : }
1371 0 : out.pushKV("bip32_derivs", keypaths);
1372 0 : }
1373 :
1374 : // Taproot internal key
1375 0 : if (!output.m_tap_internal_key.IsNull()) {
1376 0 : out.pushKV("taproot_internal_key", HexStr(output.m_tap_internal_key));
1377 0 : }
1378 :
1379 : // Taproot tree
1380 0 : if (!output.m_tap_tree.empty()) {
1381 0 : UniValue tree(UniValue::VARR);
1382 0 : for (const auto& [depth, leaf_ver, script] : output.m_tap_tree) {
1383 0 : UniValue elem(UniValue::VOBJ);
1384 0 : elem.pushKV("depth", (int)depth);
1385 0 : elem.pushKV("leaf_ver", (int)leaf_ver);
1386 0 : elem.pushKV("script", HexStr(script));
1387 0 : tree.push_back(elem);
1388 0 : }
1389 0 : out.pushKV("taproot_tree", tree);
1390 0 : }
1391 :
1392 : // Taproot bip32 keypaths
1393 0 : if (!output.m_tap_bip32_paths.empty()) {
1394 0 : UniValue keypaths(UniValue::VARR);
1395 0 : for (const auto& [xonly, leaf_origin] : output.m_tap_bip32_paths) {
1396 0 : const auto& [leaf_hashes, origin] = leaf_origin;
1397 0 : UniValue path_obj(UniValue::VOBJ);
1398 0 : path_obj.pushKV("pubkey", HexStr(xonly));
1399 0 : path_obj.pushKV("master_fingerprint", strprintf("%08x", ReadBE32(origin.fingerprint)));
1400 0 : path_obj.pushKV("path", WriteHDKeypath(origin.path));
1401 0 : UniValue leaf_hashes_arr(UniValue::VARR);
1402 0 : for (const auto& leaf_hash : leaf_hashes) {
1403 0 : leaf_hashes_arr.push_back(HexStr(leaf_hash));
1404 : }
1405 0 : path_obj.pushKV("leaf_hashes", leaf_hashes_arr);
1406 0 : keypaths.push_back(path_obj);
1407 0 : }
1408 0 : out.pushKV("taproot_bip32_derivs", keypaths);
1409 0 : }
1410 :
1411 : // Proprietary
1412 0 : if (!output.m_proprietary.empty()) {
1413 0 : UniValue proprietary(UniValue::VARR);
1414 0 : for (const auto& entry : output.m_proprietary) {
1415 0 : UniValue this_prop(UniValue::VOBJ);
1416 0 : this_prop.pushKV("identifier", HexStr(entry.identifier));
1417 0 : this_prop.pushKV("subtype", entry.subtype);
1418 0 : this_prop.pushKV("key", HexStr(entry.key));
1419 0 : this_prop.pushKV("value", HexStr(entry.value));
1420 0 : proprietary.push_back(this_prop);
1421 0 : }
1422 0 : out.pushKV("proprietary", proprietary);
1423 0 : }
1424 :
1425 : // Unknown data
1426 0 : if (output.unknown.size() > 0) {
1427 0 : UniValue unknowns(UniValue::VOBJ);
1428 0 : for (auto entry : output.unknown) {
1429 0 : unknowns.pushKV(HexStr(entry.first), HexStr(entry.second));
1430 0 : }
1431 0 : out.pushKV("unknown", unknowns);
1432 0 : }
1433 :
1434 0 : outputs.push_back(out);
1435 :
1436 : // Fee calculation
1437 0 : if (MoneyRange(psbtx.tx->vout[i].nValue) && MoneyRange(output_value + psbtx.tx->vout[i].nValue)) {
1438 0 : output_value += psbtx.tx->vout[i].nValue;
1439 0 : } else {
1440 : // Hack to just not show fee later
1441 0 : have_all_utxos = false;
1442 : }
1443 0 : }
1444 0 : result.pushKV("outputs", outputs);
1445 0 : if (have_all_utxos) {
1446 0 : result.pushKV("fee", ValueFromAmount(total_in - output_value));
1447 0 : }
1448 :
1449 0 : return result;
1450 0 : },
1451 : };
1452 0 : }
1453 :
1454 2 : static RPCHelpMan combinepsbt()
1455 : {
1456 4 : return RPCHelpMan{"combinepsbt",
1457 2 : "\nCombine multiple partially signed Bitcoin transactions into one transaction.\n"
1458 : "Implements the Combiner role.\n",
1459 4 : {
1460 4 : {"txs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The base64 strings of partially signed transactions",
1461 4 : {
1462 2 : {"psbt", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "A base64 string of a PSBT"},
1463 : },
1464 : },
1465 : },
1466 2 : RPCResult{
1467 2 : RPCResult::Type::STR, "", "The base64-encoded partially signed transaction"
1468 : },
1469 2 : RPCExamples{
1470 2 : HelpExampleCli("combinepsbt", R"('["mybase64_1", "mybase64_2", "mybase64_3"]')")
1471 : },
1472 2 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1473 : {
1474 : // Unserialize the transactions
1475 0 : std::vector<PartiallySignedTransaction> psbtxs;
1476 0 : UniValue txs = request.params[0].get_array();
1477 0 : if (txs.empty()) {
1478 0 : throw JSONRPCError(RPC_INVALID_PARAMETER, "Parameter 'txs' cannot be empty");
1479 : }
1480 0 : for (unsigned int i = 0; i < txs.size(); ++i) {
1481 0 : PartiallySignedTransaction psbtx;
1482 0 : std::string error;
1483 0 : if (!DecodeBase64PSBT(psbtx, txs[i].get_str(), error)) {
1484 0 : throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
1485 : }
1486 0 : psbtxs.push_back(psbtx);
1487 0 : }
1488 :
1489 0 : PartiallySignedTransaction merged_psbt;
1490 0 : const TransactionError error = CombinePSBTs(merged_psbt, psbtxs);
1491 0 : if (error != TransactionError::OK) {
1492 0 : throw JSONRPCTransactionError(error);
1493 : }
1494 :
1495 0 : CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
1496 0 : ssTx << merged_psbt;
1497 0 : return EncodeBase64(ssTx);
1498 0 : },
1499 : };
1500 0 : }
1501 :
1502 2 : static RPCHelpMan finalizepsbt()
1503 : {
1504 4 : return RPCHelpMan{"finalizepsbt",
1505 2 : "Finalize the inputs of a PSBT. If the transaction is fully signed, it will produce a\n"
1506 : "network serialized transaction which can be broadcast with sendrawtransaction. Otherwise a PSBT will be\n"
1507 : "created which has the final_scriptSig and final_scriptWitness fields filled for inputs that are complete.\n"
1508 : "Implements the Finalizer and Extractor roles.\n",
1509 6 : {
1510 2 : {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"},
1511 2 : {"extract", RPCArg::Type::BOOL, RPCArg::Default{true}, "If true and the transaction is complete,\n"
1512 : " extract and return the complete transaction in normal network serialization instead of the PSBT."},
1513 : },
1514 2 : RPCResult{
1515 2 : RPCResult::Type::OBJ, "", "",
1516 8 : {
1517 2 : {RPCResult::Type::STR, "psbt", /*optional=*/true, "The base64-encoded partially signed transaction if not extracted"},
1518 2 : {RPCResult::Type::STR_HEX, "hex", /*optional=*/true, "The hex-encoded network transaction if extracted"},
1519 2 : {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"},
1520 : }
1521 : },
1522 2 : RPCExamples{
1523 2 : HelpExampleCli("finalizepsbt", "\"psbt\"")
1524 : },
1525 2 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1526 : {
1527 : // Unserialize the transactions
1528 0 : PartiallySignedTransaction psbtx;
1529 0 : std::string error;
1530 0 : if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
1531 0 : throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
1532 : }
1533 :
1534 0 : bool extract = request.params[1].isNull() || (!request.params[1].isNull() && request.params[1].get_bool());
1535 :
1536 0 : CMutableTransaction mtx;
1537 0 : bool complete = FinalizeAndExtractPSBT(psbtx, mtx);
1538 :
1539 0 : UniValue result(UniValue::VOBJ);
1540 0 : CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
1541 0 : std::string result_str;
1542 :
1543 0 : if (complete && extract) {
1544 0 : ssTx << mtx;
1545 0 : result_str = HexStr(ssTx);
1546 0 : result.pushKV("hex", result_str);
1547 0 : } else {
1548 0 : ssTx << psbtx;
1549 0 : result_str = EncodeBase64(ssTx.str());
1550 0 : result.pushKV("psbt", result_str);
1551 : }
1552 0 : result.pushKV("complete", complete);
1553 :
1554 0 : return result;
1555 0 : },
1556 : };
1557 0 : }
1558 :
1559 2 : static RPCHelpMan createpsbt()
1560 : {
1561 4 : return RPCHelpMan{"createpsbt",
1562 2 : "\nCreates a transaction in the Partially Signed Transaction format.\n"
1563 : "Implements the Creator role.\n",
1564 2 : CreateTxDoc(),
1565 2 : RPCResult{
1566 2 : RPCResult::Type::STR, "", "The resulting raw transaction (base64-encoded string)"
1567 : },
1568 2 : RPCExamples{
1569 2 : HelpExampleCli("createpsbt", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"")
1570 : },
1571 2 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1572 : {
1573 :
1574 0 : std::optional<bool> rbf;
1575 0 : if (!request.params[3].isNull()) {
1576 0 : rbf = request.params[3].get_bool();
1577 0 : }
1578 0 : CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], rbf);
1579 :
1580 : // Make a blank psbt
1581 0 : PartiallySignedTransaction psbtx;
1582 0 : psbtx.tx = rawTx;
1583 0 : for (unsigned int i = 0; i < rawTx.vin.size(); ++i) {
1584 0 : psbtx.inputs.push_back(PSBTInput());
1585 0 : }
1586 0 : for (unsigned int i = 0; i < rawTx.vout.size(); ++i) {
1587 0 : psbtx.outputs.push_back(PSBTOutput());
1588 0 : }
1589 :
1590 : // Serialize the PSBT
1591 0 : CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
1592 0 : ssTx << psbtx;
1593 :
1594 0 : return EncodeBase64(ssTx);
1595 0 : },
1596 : };
1597 0 : }
1598 :
1599 2 : static RPCHelpMan converttopsbt()
1600 : {
1601 4 : return RPCHelpMan{"converttopsbt",
1602 2 : "\nConverts a network serialized transaction to a PSBT. This should be used only with createrawtransaction and fundrawtransaction\n"
1603 : "createpsbt and walletcreatefundedpsbt should be used for new applications.\n",
1604 8 : {
1605 2 : {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of a raw transaction"},
1606 2 : {"permitsigdata", RPCArg::Type::BOOL, RPCArg::Default{false}, "If true, any signatures in the input will be discarded and conversion\n"
1607 : " will continue. If false, RPC will fail if any signatures are present."},
1608 2 : {"iswitness", RPCArg::Type::BOOL, RPCArg::DefaultHint{"depends on heuristic tests"}, "Whether the transaction hex is a serialized witness transaction.\n"
1609 : "If iswitness is not present, heuristic tests will be used in decoding.\n"
1610 : "If true, only witness deserialization will be tried.\n"
1611 : "If false, only non-witness deserialization will be tried.\n"
1612 : "This boolean should reflect whether the transaction has inputs\n"
1613 : "(e.g. fully valid, or on-chain transactions), if known by the caller."
1614 : },
1615 : },
1616 2 : RPCResult{
1617 2 : RPCResult::Type::STR, "", "The resulting raw transaction (base64-encoded string)"
1618 : },
1619 2 : RPCExamples{
1620 : "\nCreate a transaction\n"
1621 2 : + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") +
1622 : "\nConvert the transaction to a PSBT\n"
1623 2 : + HelpExampleCli("converttopsbt", "\"rawtransaction\"")
1624 : },
1625 2 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1626 : {
1627 : // parse hex string from parameter
1628 0 : CMutableTransaction tx;
1629 0 : bool permitsigdata = request.params[1].isNull() ? false : request.params[1].get_bool();
1630 0 : bool witness_specified = !request.params[2].isNull();
1631 0 : bool iswitness = witness_specified ? request.params[2].get_bool() : false;
1632 0 : const bool try_witness = witness_specified ? iswitness : true;
1633 0 : const bool try_no_witness = witness_specified ? !iswitness : true;
1634 0 : if (!DecodeHexTx(tx, request.params[0].get_str(), try_no_witness, try_witness)) {
1635 0 : throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
1636 : }
1637 :
1638 : // Remove all scriptSigs and scriptWitnesses from inputs
1639 0 : for (CTxIn& input : tx.vin) {
1640 0 : if ((!input.scriptSig.empty() || !input.scriptWitness.IsNull()) && !permitsigdata) {
1641 0 : throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Inputs must not have scriptSigs and scriptWitnesses");
1642 : }
1643 0 : input.scriptSig.clear();
1644 0 : input.scriptWitness.SetNull();
1645 : }
1646 :
1647 : // Make a blank psbt
1648 0 : PartiallySignedTransaction psbtx;
1649 0 : psbtx.tx = tx;
1650 0 : for (unsigned int i = 0; i < tx.vin.size(); ++i) {
1651 0 : psbtx.inputs.push_back(PSBTInput());
1652 0 : }
1653 0 : for (unsigned int i = 0; i < tx.vout.size(); ++i) {
1654 0 : psbtx.outputs.push_back(PSBTOutput());
1655 0 : }
1656 :
1657 : // Serialize the PSBT
1658 0 : CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
1659 0 : ssTx << psbtx;
1660 :
1661 0 : return EncodeBase64(ssTx);
1662 0 : },
1663 : };
1664 0 : }
1665 :
1666 2 : static RPCHelpMan utxoupdatepsbt()
1667 : {
1668 4 : return RPCHelpMan{"utxoupdatepsbt",
1669 2 : "\nUpdates all segwit inputs and outputs in a PSBT with data from output descriptors, the UTXO set, txindex, or the mempool.\n",
1670 6 : {
1671 2 : {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"},
1672 6 : {"descriptors", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "An array of either strings or objects", {
1673 2 : {"", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "An output descriptor"},
1674 6 : {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "An object with an output descriptor and extra information", {
1675 2 : {"desc", RPCArg::Type::STR, RPCArg::Optional::NO, "An output descriptor"},
1676 2 : {"range", RPCArg::Type::RANGE, RPCArg::Default{1000}, "Up to what index HD chains should be explored (either end or [begin,end])"},
1677 : }},
1678 : }},
1679 : },
1680 2 : RPCResult {
1681 2 : RPCResult::Type::STR, "", "The base64-encoded partially signed transaction with inputs updated"
1682 : },
1683 2 : RPCExamples {
1684 2 : HelpExampleCli("utxoupdatepsbt", "\"psbt\"")
1685 : },
1686 2 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1687 : {
1688 : // Parse descriptors, if any.
1689 0 : FlatSigningProvider provider;
1690 0 : if (!request.params[1].isNull()) {
1691 0 : auto descs = request.params[1].get_array();
1692 0 : for (size_t i = 0; i < descs.size(); ++i) {
1693 0 : EvalDescriptorStringOrObject(descs[i], provider);
1694 0 : }
1695 0 : }
1696 :
1697 : // We don't actually need private keys further on; hide them as a precaution.
1698 0 : const PartiallySignedTransaction& psbtx = ProcessPSBT(
1699 0 : request.params[0].get_str(),
1700 0 : request.context,
1701 0 : HidingSigningProvider(&provider, /*hide_secret=*/true, /*hide_origin=*/false),
1702 : /*sighash_type=*/SIGHASH_ALL,
1703 : /*finalize=*/false);
1704 :
1705 0 : CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
1706 0 : ssTx << psbtx;
1707 0 : return EncodeBase64(ssTx);
1708 0 : },
1709 : };
1710 0 : }
1711 :
1712 2 : static RPCHelpMan joinpsbts()
1713 : {
1714 4 : return RPCHelpMan{"joinpsbts",
1715 2 : "\nJoins multiple distinct PSBTs with different inputs and outputs into one PSBT with inputs and outputs from all of the PSBTs\n"
1716 : "No input in any of the PSBTs can be in more than one of the PSBTs.\n",
1717 4 : {
1718 4 : {"txs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The base64 strings of partially signed transactions",
1719 4 : {
1720 2 : {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"}
1721 : }}
1722 : },
1723 2 : RPCResult {
1724 2 : RPCResult::Type::STR, "", "The base64-encoded partially signed transaction"
1725 : },
1726 2 : RPCExamples {
1727 2 : HelpExampleCli("joinpsbts", "\"psbt\"")
1728 : },
1729 2 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1730 : {
1731 : // Unserialize the transactions
1732 0 : std::vector<PartiallySignedTransaction> psbtxs;
1733 0 : UniValue txs = request.params[0].get_array();
1734 :
1735 0 : if (txs.size() <= 1) {
1736 0 : throw JSONRPCError(RPC_INVALID_PARAMETER, "At least two PSBTs are required to join PSBTs.");
1737 : }
1738 :
1739 0 : uint32_t best_version = 1;
1740 0 : uint32_t best_locktime = 0xffffffff;
1741 0 : for (unsigned int i = 0; i < txs.size(); ++i) {
1742 0 : PartiallySignedTransaction psbtx;
1743 0 : std::string error;
1744 0 : if (!DecodeBase64PSBT(psbtx, txs[i].get_str(), error)) {
1745 0 : throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
1746 : }
1747 0 : psbtxs.push_back(psbtx);
1748 : // Choose the highest version number
1749 0 : if (static_cast<uint32_t>(psbtx.tx->nVersion) > best_version) {
1750 0 : best_version = static_cast<uint32_t>(psbtx.tx->nVersion);
1751 0 : }
1752 : // Choose the lowest lock time
1753 0 : if (psbtx.tx->nLockTime < best_locktime) {
1754 0 : best_locktime = psbtx.tx->nLockTime;
1755 0 : }
1756 0 : }
1757 :
1758 : // Create a blank psbt where everything will be added
1759 0 : PartiallySignedTransaction merged_psbt;
1760 0 : merged_psbt.tx = CMutableTransaction();
1761 0 : merged_psbt.tx->nVersion = static_cast<int32_t>(best_version);
1762 0 : merged_psbt.tx->nLockTime = best_locktime;
1763 :
1764 : // Merge
1765 0 : for (auto& psbt : psbtxs) {
1766 0 : for (unsigned int i = 0; i < psbt.tx->vin.size(); ++i) {
1767 0 : if (!merged_psbt.AddInput(psbt.tx->vin[i], psbt.inputs[i])) {
1768 0 : throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Input %s:%d exists in multiple PSBTs", psbt.tx->vin[i].prevout.hash.ToString(), psbt.tx->vin[i].prevout.n));
1769 : }
1770 0 : }
1771 0 : for (unsigned int i = 0; i < psbt.tx->vout.size(); ++i) {
1772 0 : merged_psbt.AddOutput(psbt.tx->vout[i], psbt.outputs[i]);
1773 0 : }
1774 0 : for (auto& xpub_pair : psbt.m_xpubs) {
1775 0 : if (merged_psbt.m_xpubs.count(xpub_pair.first) == 0) {
1776 0 : merged_psbt.m_xpubs[xpub_pair.first] = xpub_pair.second;
1777 0 : } else {
1778 0 : merged_psbt.m_xpubs[xpub_pair.first].insert(xpub_pair.second.begin(), xpub_pair.second.end());
1779 : }
1780 : }
1781 0 : merged_psbt.unknown.insert(psbt.unknown.begin(), psbt.unknown.end());
1782 : }
1783 :
1784 : // Generate list of shuffled indices for shuffling inputs and outputs of the merged PSBT
1785 0 : std::vector<int> input_indices(merged_psbt.inputs.size());
1786 0 : std::iota(input_indices.begin(), input_indices.end(), 0);
1787 0 : std::vector<int> output_indices(merged_psbt.outputs.size());
1788 0 : std::iota(output_indices.begin(), output_indices.end(), 0);
1789 :
1790 : // Shuffle input and output indices lists
1791 0 : Shuffle(input_indices.begin(), input_indices.end(), FastRandomContext());
1792 0 : Shuffle(output_indices.begin(), output_indices.end(), FastRandomContext());
1793 :
1794 0 : PartiallySignedTransaction shuffled_psbt;
1795 0 : shuffled_psbt.tx = CMutableTransaction();
1796 0 : shuffled_psbt.tx->nVersion = merged_psbt.tx->nVersion;
1797 0 : shuffled_psbt.tx->nLockTime = merged_psbt.tx->nLockTime;
1798 0 : for (int i : input_indices) {
1799 0 : shuffled_psbt.AddInput(merged_psbt.tx->vin[i], merged_psbt.inputs[i]);
1800 : }
1801 0 : for (int i : output_indices) {
1802 0 : shuffled_psbt.AddOutput(merged_psbt.tx->vout[i], merged_psbt.outputs[i]);
1803 : }
1804 0 : shuffled_psbt.unknown.insert(merged_psbt.unknown.begin(), merged_psbt.unknown.end());
1805 :
1806 0 : CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
1807 0 : ssTx << shuffled_psbt;
1808 0 : return EncodeBase64(ssTx);
1809 0 : },
1810 : };
1811 0 : }
1812 :
1813 2 : static RPCHelpMan analyzepsbt()
1814 : {
1815 4 : return RPCHelpMan{"analyzepsbt",
1816 2 : "\nAnalyzes and provides information about the current status of a PSBT and its inputs\n",
1817 4 : {
1818 2 : {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"}
1819 : },
1820 2 : RPCResult {
1821 2 : RPCResult::Type::OBJ, "", "",
1822 14 : {
1823 4 : {RPCResult::Type::ARR, "inputs", /*optional=*/true, "",
1824 4 : {
1825 4 : {RPCResult::Type::OBJ, "", "",
1826 10 : {
1827 2 : {RPCResult::Type::BOOL, "has_utxo", "Whether a UTXO is provided"},
1828 2 : {RPCResult::Type::BOOL, "is_final", "Whether the input is finalized"},
1829 4 : {RPCResult::Type::OBJ, "missing", /*optional=*/true, "Things that are missing that are required to complete this input",
1830 10 : {
1831 4 : {RPCResult::Type::ARR, "pubkeys", /*optional=*/true, "",
1832 4 : {
1833 2 : {RPCResult::Type::STR_HEX, "keyid", "Public key ID, hash160 of the public key, of a public key whose BIP 32 derivation path is missing"},
1834 : }},
1835 4 : {RPCResult::Type::ARR, "signatures", /*optional=*/true, "",
1836 4 : {
1837 2 : {RPCResult::Type::STR_HEX, "keyid", "Public key ID, hash160 of the public key, of a public key whose signature is missing"},
1838 : }},
1839 2 : {RPCResult::Type::STR_HEX, "redeemscript", /*optional=*/true, "Hash160 of the redeemScript that is missing"},
1840 2 : {RPCResult::Type::STR_HEX, "witnessscript", /*optional=*/true, "SHA256 of the witnessScript that is missing"},
1841 : }},
1842 2 : {RPCResult::Type::STR, "next", /*optional=*/true, "Role of the next person that this input needs to go to"},
1843 : }},
1844 : }},
1845 2 : {RPCResult::Type::NUM, "estimated_vsize", /*optional=*/true, "Estimated vsize of the final signed transaction"},
1846 2 : {RPCResult::Type::STR_AMOUNT, "estimated_feerate", /*optional=*/true, "Estimated feerate of the final signed transaction in " + CURRENCY_UNIT + "/kvB. Shown only if all UTXO slots in the PSBT have been filled"},
1847 2 : {RPCResult::Type::STR_AMOUNT, "fee", /*optional=*/true, "The transaction fee paid. Shown only if all UTXO slots in the PSBT have been filled"},
1848 2 : {RPCResult::Type::STR, "next", "Role of the next person that this psbt needs to go to"},
1849 2 : {RPCResult::Type::STR, "error", /*optional=*/true, "Error message (if there is one)"},
1850 : }
1851 : },
1852 2 : RPCExamples {
1853 2 : HelpExampleCli("analyzepsbt", "\"psbt\"")
1854 : },
1855 2 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1856 : {
1857 : // Unserialize the transaction
1858 0 : PartiallySignedTransaction psbtx;
1859 0 : std::string error;
1860 0 : if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
1861 0 : throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
1862 : }
1863 :
1864 0 : PSBTAnalysis psbta = AnalyzePSBT(psbtx);
1865 :
1866 0 : UniValue result(UniValue::VOBJ);
1867 0 : UniValue inputs_result(UniValue::VARR);
1868 0 : for (const auto& input : psbta.inputs) {
1869 0 : UniValue input_univ(UniValue::VOBJ);
1870 0 : UniValue missing(UniValue::VOBJ);
1871 :
1872 0 : input_univ.pushKV("has_utxo", input.has_utxo);
1873 0 : input_univ.pushKV("is_final", input.is_final);
1874 0 : input_univ.pushKV("next", PSBTRoleName(input.next));
1875 :
1876 0 : if (!input.missing_pubkeys.empty()) {
1877 0 : UniValue missing_pubkeys_univ(UniValue::VARR);
1878 0 : for (const CKeyID& pubkey : input.missing_pubkeys) {
1879 0 : missing_pubkeys_univ.push_back(HexStr(pubkey));
1880 : }
1881 0 : missing.pushKV("pubkeys", missing_pubkeys_univ);
1882 0 : }
1883 0 : if (!input.missing_redeem_script.IsNull()) {
1884 0 : missing.pushKV("redeemscript", HexStr(input.missing_redeem_script));
1885 0 : }
1886 0 : if (!input.missing_witness_script.IsNull()) {
1887 0 : missing.pushKV("witnessscript", HexStr(input.missing_witness_script));
1888 0 : }
1889 0 : if (!input.missing_sigs.empty()) {
1890 0 : UniValue missing_sigs_univ(UniValue::VARR);
1891 0 : for (const CKeyID& pubkey : input.missing_sigs) {
1892 0 : missing_sigs_univ.push_back(HexStr(pubkey));
1893 : }
1894 0 : missing.pushKV("signatures", missing_sigs_univ);
1895 0 : }
1896 0 : if (!missing.getKeys().empty()) {
1897 0 : input_univ.pushKV("missing", missing);
1898 0 : }
1899 0 : inputs_result.push_back(input_univ);
1900 0 : }
1901 0 : if (!inputs_result.empty()) result.pushKV("inputs", inputs_result);
1902 :
1903 0 : if (psbta.estimated_vsize != std::nullopt) {
1904 0 : result.pushKV("estimated_vsize", (int)*psbta.estimated_vsize);
1905 0 : }
1906 0 : if (psbta.estimated_feerate != std::nullopt) {
1907 0 : result.pushKV("estimated_feerate", ValueFromAmount(psbta.estimated_feerate->GetFeePerK()));
1908 0 : }
1909 0 : if (psbta.fee != std::nullopt) {
1910 0 : result.pushKV("fee", ValueFromAmount(*psbta.fee));
1911 0 : }
1912 0 : result.pushKV("next", PSBTRoleName(psbta.next));
1913 0 : if (!psbta.error.empty()) {
1914 0 : result.pushKV("error", psbta.error);
1915 0 : }
1916 :
1917 0 : return result;
1918 0 : },
1919 : };
1920 0 : }
1921 :
1922 2 : RPCHelpMan descriptorprocesspsbt()
1923 : {
1924 4 : return RPCHelpMan{"descriptorprocesspsbt",
1925 2 : "\nUpdate all segwit inputs in a PSBT with information from output descriptors, the UTXO set or the mempool. \n"
1926 : "Then, sign the inputs we are able to with information from the output descriptors. ",
1927 12 : {
1928 2 : {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction base64 string"},
1929 6 : {"descriptors", RPCArg::Type::ARR, RPCArg::Optional::NO, "An array of either strings or objects", {
1930 2 : {"", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "An output descriptor"},
1931 6 : {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "An object with an output descriptor and extra information", {
1932 2 : {"desc", RPCArg::Type::STR, RPCArg::Optional::NO, "An output descriptor"},
1933 2 : {"range", RPCArg::Type::RANGE, RPCArg::Default{1000}, "Up to what index HD chains should be explored (either end or [begin,end])"},
1934 : }},
1935 : }},
1936 2 : {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"DEFAULT for Taproot, ALL otherwise"}, "The signature hash type to sign with if not specified by the PSBT. Must be one of\n"
1937 : " \"DEFAULT\"\n"
1938 : " \"ALL\"\n"
1939 : " \"NONE\"\n"
1940 : " \"SINGLE\"\n"
1941 : " \"ALL|ANYONECANPAY\"\n"
1942 : " \"NONE|ANYONECANPAY\"\n"
1943 : " \"SINGLE|ANYONECANPAY\""},
1944 2 : {"bip32derivs", RPCArg::Type::BOOL, RPCArg::Default{true}, "Include BIP 32 derivation paths for public keys if we know them"},
1945 2 : {"finalize", RPCArg::Type::BOOL, RPCArg::Default{true}, "Also finalize inputs if possible"},
1946 : },
1947 2 : RPCResult{
1948 2 : RPCResult::Type::OBJ, "", "",
1949 6 : {
1950 2 : {RPCResult::Type::STR, "psbt", "The base64-encoded partially signed transaction"},
1951 2 : {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"},
1952 : }
1953 : },
1954 2 : RPCExamples{
1955 4 : HelpExampleCli("descriptorprocesspsbt", "\"psbt\" \"[\\\"descriptor1\\\", \\\"descriptor2\\\"]\"") +
1956 2 : HelpExampleCli("descriptorprocesspsbt", "\"psbt\" \"[{\\\"desc\\\":\\\"mydescriptor\\\", \\\"range\\\":21}]\"")
1957 : },
1958 2 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1959 : {
1960 : // Add descriptor information to a signing provider
1961 0 : FlatSigningProvider provider;
1962 :
1963 0 : auto descs = request.params[1].get_array();
1964 0 : for (size_t i = 0; i < descs.size(); ++i) {
1965 0 : EvalDescriptorStringOrObject(descs[i], provider, /*expand_priv=*/true);
1966 0 : }
1967 :
1968 0 : int sighash_type = ParseSighashString(request.params[2]);
1969 0 : bool bip32derivs = request.params[3].isNull() ? true : request.params[3].get_bool();
1970 0 : bool finalize = request.params[4].isNull() ? true : request.params[4].get_bool();
1971 :
1972 0 : const PartiallySignedTransaction& psbtx = ProcessPSBT(
1973 0 : request.params[0].get_str(),
1974 0 : request.context,
1975 0 : HidingSigningProvider(&provider, /*hide_secret=*/false, !bip32derivs),
1976 0 : sighash_type,
1977 0 : finalize);
1978 :
1979 : // Check whether or not all of the inputs are now signed
1980 0 : bool complete = true;
1981 0 : for (const auto& input : psbtx.inputs) {
1982 0 : complete &= PSBTInputSigned(input);
1983 : }
1984 :
1985 0 : CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
1986 0 : ssTx << psbtx;
1987 :
1988 0 : UniValue result(UniValue::VOBJ);
1989 :
1990 0 : result.pushKV("psbt", EncodeBase64(ssTx));
1991 0 : result.pushKV("complete", complete);
1992 :
1993 0 : return result;
1994 0 : },
1995 : };
1996 0 : }
1997 :
1998 1 : void RegisterRawTransactionRPCCommands(CRPCTable& t)
1999 : {
2000 16 : static const CRPCCommand commands[]{
2001 1 : {"rawtransactions", &getrawtransaction},
2002 1 : {"rawtransactions", &createrawtransaction},
2003 1 : {"rawtransactions", &decoderawtransaction},
2004 1 : {"rawtransactions", &decodescript},
2005 1 : {"rawtransactions", &combinerawtransaction},
2006 1 : {"rawtransactions", &signrawtransactionwithkey},
2007 1 : {"rawtransactions", &decodepsbt},
2008 1 : {"rawtransactions", &combinepsbt},
2009 1 : {"rawtransactions", &finalizepsbt},
2010 1 : {"rawtransactions", &createpsbt},
2011 1 : {"rawtransactions", &converttopsbt},
2012 1 : {"rawtransactions", &utxoupdatepsbt},
2013 1 : {"rawtransactions", &descriptorprocesspsbt},
2014 1 : {"rawtransactions", &joinpsbts},
2015 1 : {"rawtransactions", &analyzepsbt},
2016 : };
2017 16 : for (const auto& c : commands) {
2018 15 : t.appendCommand(c.name, &c);
2019 : }
2020 1 : }
|