Merge #10749: Use compile-time constants instead of unnamed enumerations (remove...
[bitcoinplatinum.git] / src / rpc / rawtransaction.cpp
blobd860dbc24457d3f6fcbcd5aec9f68ee1fa107099
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.
6 #include "base58.h"
7 #include "chain.h"
8 #include "coins.h"
9 #include "consensus/validation.h"
10 #include "core_io.h"
11 #include "init.h"
12 #include "keystore.h"
13 #include "validation.h"
14 #include "merkleblock.h"
15 #include "net.h"
16 #include "policy/policy.h"
17 #include "policy/rbf.h"
18 #include "primitives/transaction.h"
19 #include "rpc/safemode.h"
20 #include "rpc/server.h"
21 #include "script/script.h"
22 #include "script/script_error.h"
23 #include "script/sign.h"
24 #include "script/standard.h"
25 #include "txmempool.h"
26 #include "uint256.h"
27 #include "utilstrencodings.h"
28 #ifdef ENABLE_WALLET
29 #include "wallet/rpcwallet.h"
30 #include "wallet/wallet.h"
31 #endif
33 #include <stdint.h>
35 #include <univalue.h>
38 void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
40 // Call into TxToUniv() in bitcoin-common to decode the transaction hex.
42 // Blockchain contextual information (confirmations and blocktime) is not
43 // available to code in bitcoin-common, so we query them here and push the
44 // data into the returned UniValue.
45 TxToUniv(tx, uint256(), entry, true, RPCSerializationFlags());
47 if (!hashBlock.IsNull()) {
48 entry.push_back(Pair("blockhash", hashBlock.GetHex()));
49 BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
50 if (mi != mapBlockIndex.end() && (*mi).second) {
51 CBlockIndex* pindex = (*mi).second;
52 if (chainActive.Contains(pindex)) {
53 entry.push_back(Pair("confirmations", 1 + chainActive.Height() - pindex->nHeight));
54 entry.push_back(Pair("time", pindex->GetBlockTime()));
55 entry.push_back(Pair("blocktime", pindex->GetBlockTime()));
57 else
58 entry.push_back(Pair("confirmations", 0));
63 UniValue getrawtransaction(const JSONRPCRequest& request)
65 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
66 throw std::runtime_error(
67 "getrawtransaction \"txid\" ( verbose )\n"
69 "\nNOTE: By default this function only works for mempool transactions. If the -txindex option is\n"
70 "enabled, it also works for blockchain transactions.\n"
71 "DEPRECATED: for now, it also works for transactions with unspent outputs.\n"
73 "\nReturn the raw transaction data.\n"
74 "\nIf verbose is 'true', returns an Object with information about 'txid'.\n"
75 "If verbose is 'false' or omitted, returns a string that is serialized, hex-encoded data for 'txid'.\n"
77 "\nArguments:\n"
78 "1. \"txid\" (string, required) The transaction id\n"
79 "2. verbose (bool, optional, default=false) If false, return a string, otherwise return a json object\n"
81 "\nResult (if verbose is not set or set to false):\n"
82 "\"data\" (string) The serialized, hex-encoded data for 'txid'\n"
84 "\nResult (if verbose is set to true):\n"
85 "{\n"
86 " \"hex\" : \"data\", (string) The serialized, hex-encoded data for 'txid'\n"
87 " \"txid\" : \"id\", (string) The transaction id (same as provided)\n"
88 " \"hash\" : \"id\", (string) The transaction hash (differs from txid for witness transactions)\n"
89 " \"size\" : n, (numeric) The serialized transaction size\n"
90 " \"vsize\" : n, (numeric) The virtual transaction size (differs from size for witness transactions)\n"
91 " \"version\" : n, (numeric) The version\n"
92 " \"locktime\" : ttt, (numeric) The lock time\n"
93 " \"vin\" : [ (array of json objects)\n"
94 " {\n"
95 " \"txid\": \"id\", (string) The transaction id\n"
96 " \"vout\": n, (numeric) \n"
97 " \"scriptSig\": { (json object) The script\n"
98 " \"asm\": \"asm\", (string) asm\n"
99 " \"hex\": \"hex\" (string) hex\n"
100 " },\n"
101 " \"sequence\": n (numeric) The script sequence number\n"
102 " \"txinwitness\": [\"hex\", ...] (array of string) hex-encoded witness data (if any)\n"
103 " }\n"
104 " ,...\n"
105 " ],\n"
106 " \"vout\" : [ (array of json objects)\n"
107 " {\n"
108 " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n"
109 " \"n\" : n, (numeric) index\n"
110 " \"scriptPubKey\" : { (json object)\n"
111 " \"asm\" : \"asm\", (string) the asm\n"
112 " \"hex\" : \"hex\", (string) the hex\n"
113 " \"reqSigs\" : n, (numeric) The required sigs\n"
114 " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
115 " \"addresses\" : [ (json array of string)\n"
116 " \"address\" (string) bitcoin address\n"
117 " ,...\n"
118 " ]\n"
119 " }\n"
120 " }\n"
121 " ,...\n"
122 " ],\n"
123 " \"blockhash\" : \"hash\", (string) the block hash\n"
124 " \"confirmations\" : n, (numeric) The confirmations\n"
125 " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT)\n"
126 " \"blocktime\" : ttt (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
127 "}\n"
129 "\nExamples:\n"
130 + HelpExampleCli("getrawtransaction", "\"mytxid\"")
131 + HelpExampleCli("getrawtransaction", "\"mytxid\" true")
132 + HelpExampleRpc("getrawtransaction", "\"mytxid\", true")
135 LOCK(cs_main);
137 uint256 hash = ParseHashV(request.params[0], "parameter 1");
139 // Accept either a bool (true) or a num (>=1) to indicate verbose output.
140 bool fVerbose = false;
141 if (!request.params[1].isNull()) {
142 if (request.params[1].isNum()) {
143 if (request.params[1].get_int() != 0) {
144 fVerbose = true;
147 else if(request.params[1].isBool()) {
148 if(request.params[1].isTrue()) {
149 fVerbose = true;
152 else {
153 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid type provided. Verbose parameter must be a boolean.");
157 CTransactionRef tx;
158 uint256 hashBlock;
159 if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true))
160 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string(fTxIndex ? "No such mempool or blockchain transaction"
161 : "No such mempool transaction. Use -txindex to enable blockchain transaction queries") +
162 ". Use gettransaction for wallet transactions.");
164 if (!fVerbose)
165 return EncodeHexTx(*tx, RPCSerializationFlags());
167 UniValue result(UniValue::VOBJ);
168 TxToJSON(*tx, hashBlock, result);
169 return result;
172 UniValue gettxoutproof(const JSONRPCRequest& request)
174 if (request.fHelp || (request.params.size() != 1 && request.params.size() != 2))
175 throw std::runtime_error(
176 "gettxoutproof [\"txid\",...] ( blockhash )\n"
177 "\nReturns a hex-encoded proof that \"txid\" was included in a block.\n"
178 "\nNOTE: By default this function only works sometimes. This is when there is an\n"
179 "unspent output in the utxo for this transaction. To make it always work,\n"
180 "you need to maintain a transaction index, using the -txindex command line option or\n"
181 "specify the block in which the transaction is included manually (by blockhash).\n"
182 "\nArguments:\n"
183 "1. \"txids\" (string) A json array of txids to filter\n"
184 " [\n"
185 " \"txid\" (string) A transaction hash\n"
186 " ,...\n"
187 " ]\n"
188 "2. \"blockhash\" (string, optional) If specified, looks for txid in the block with this hash\n"
189 "\nResult:\n"
190 "\"data\" (string) A string that is a serialized, hex-encoded data for the proof.\n"
193 std::set<uint256> setTxids;
194 uint256 oneTxid;
195 UniValue txids = request.params[0].get_array();
196 for (unsigned int idx = 0; idx < txids.size(); idx++) {
197 const UniValue& txid = txids[idx];
198 if (txid.get_str().length() != 64 || !IsHex(txid.get_str()))
199 throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid txid ")+txid.get_str());
200 uint256 hash(uint256S(txid.get_str()));
201 if (setTxids.count(hash))
202 throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated txid: ")+txid.get_str());
203 setTxids.insert(hash);
204 oneTxid = hash;
207 LOCK(cs_main);
209 CBlockIndex* pblockindex = nullptr;
211 uint256 hashBlock;
212 if (!request.params[1].isNull())
214 hashBlock = uint256S(request.params[1].get_str());
215 if (!mapBlockIndex.count(hashBlock))
216 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
217 pblockindex = mapBlockIndex[hashBlock];
218 } else {
219 // Loop through txids and try to find which block they're in. Exit loop once a block is found.
220 for (const auto& tx : setTxids) {
221 const Coin& coin = AccessByTxid(*pcoinsTip, tx);
222 if (!coin.IsSpent()) {
223 pblockindex = chainActive[coin.nHeight];
224 break;
229 if (pblockindex == nullptr)
231 CTransactionRef tx;
232 if (!GetTransaction(oneTxid, tx, Params().GetConsensus(), hashBlock, false) || hashBlock.IsNull())
233 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block");
234 if (!mapBlockIndex.count(hashBlock))
235 throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt");
236 pblockindex = mapBlockIndex[hashBlock];
239 CBlock block;
240 if(!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
241 throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
243 unsigned int ntxFound = 0;
244 for (const auto& tx : block.vtx)
245 if (setTxids.count(tx->GetHash()))
246 ntxFound++;
247 if (ntxFound != setTxids.size())
248 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Not all transactions found in specified or retrieved block");
250 CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS);
251 CMerkleBlock mb(block, setTxids);
252 ssMB << mb;
253 std::string strHex = HexStr(ssMB.begin(), ssMB.end());
254 return strHex;
257 UniValue verifytxoutproof(const JSONRPCRequest& request)
259 if (request.fHelp || request.params.size() != 1)
260 throw std::runtime_error(
261 "verifytxoutproof \"proof\"\n"
262 "\nVerifies that a proof points to a transaction in a block, returning the transaction it commits to\n"
263 "and throwing an RPC error if the block is not in our best chain\n"
264 "\nArguments:\n"
265 "1. \"proof\" (string, required) The hex-encoded proof generated by gettxoutproof\n"
266 "\nResult:\n"
267 "[\"txid\"] (array, strings) The txid(s) which the proof commits to, or empty array if the proof is invalid\n"
270 CDataStream ssMB(ParseHexV(request.params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS);
271 CMerkleBlock merkleBlock;
272 ssMB >> merkleBlock;
274 UniValue res(UniValue::VARR);
276 std::vector<uint256> vMatch;
277 std::vector<unsigned int> vIndex;
278 if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) != merkleBlock.header.hashMerkleRoot)
279 return res;
281 LOCK(cs_main);
283 if (!mapBlockIndex.count(merkleBlock.header.GetHash()) || !chainActive.Contains(mapBlockIndex[merkleBlock.header.GetHash()]))
284 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain");
286 for (const uint256& hash : vMatch)
287 res.push_back(hash.GetHex());
288 return res;
291 UniValue createrawtransaction(const JSONRPCRequest& request)
293 if (request.fHelp || request.params.size() < 2 || request.params.size() > 4)
294 throw std::runtime_error(
295 "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,\"data\":\"hex\",...} ( locktime ) ( replaceable )\n"
296 "\nCreate a transaction spending the given inputs and creating new outputs.\n"
297 "Outputs can be addresses or data.\n"
298 "Returns hex-encoded raw transaction.\n"
299 "Note that the transaction's inputs are not signed, and\n"
300 "it is not stored in the wallet or transmitted to the network.\n"
302 "\nArguments:\n"
303 "1. \"inputs\" (array, required) A json array of json objects\n"
304 " [\n"
305 " {\n"
306 " \"txid\":\"id\", (string, required) The transaction id\n"
307 " \"vout\":n, (numeric, required) The output number\n"
308 " \"sequence\":n (numeric, optional) The sequence number\n"
309 " } \n"
310 " ,...\n"
311 " ]\n"
312 "2. \"outputs\" (object, required) a json object with outputs\n"
313 " {\n"
314 " \"address\": x.xxx, (numeric or string, required) The key is the bitcoin address, the numeric value (can be string) is the " + CURRENCY_UNIT + " amount\n"
315 " \"data\": \"hex\" (string, required) The key is \"data\", the value is hex encoded data\n"
316 " ,...\n"
317 " }\n"
318 "3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n"
319 "4. replaceable (boolean, optional, default=false) Marks this transaction as BIP125 replaceable.\n"
320 " Allows this transaction to be replaced by a transaction with higher fees. If provided, it is an error if explicit sequence numbers are incompatible.\n"
321 "\nResult:\n"
322 "\"transaction\" (string) hex string of the transaction\n"
324 "\nExamples:\n"
325 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":0.01}\"")
326 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"data\\\":\\\"00010203\\\"}\"")
327 + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\"")
328 + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"data\\\":\\\"00010203\\\"}\"")
331 RPCTypeCheck(request.params, {UniValue::VARR, UniValue::VOBJ, UniValue::VNUM}, true);
332 if (request.params[0].isNull() || request.params[1].isNull())
333 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, arguments 1 and 2 must be non-null");
335 UniValue inputs = request.params[0].get_array();
336 UniValue sendTo = request.params[1].get_obj();
338 CMutableTransaction rawTx;
340 if (!request.params[2].isNull()) {
341 int64_t nLockTime = request.params[2].get_int64();
342 if (nLockTime < 0 || nLockTime > std::numeric_limits<uint32_t>::max())
343 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, locktime out of range");
344 rawTx.nLockTime = nLockTime;
347 bool rbfOptIn = request.params[3].isTrue();
349 for (unsigned int idx = 0; idx < inputs.size(); idx++) {
350 const UniValue& input = inputs[idx];
351 const UniValue& o = input.get_obj();
353 uint256 txid = ParseHashO(o, "txid");
355 const UniValue& vout_v = find_value(o, "vout");
356 if (!vout_v.isNum())
357 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");
358 int nOutput = vout_v.get_int();
359 if (nOutput < 0)
360 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
362 uint32_t nSequence;
363 if (rbfOptIn) {
364 nSequence = MAX_BIP125_RBF_SEQUENCE;
365 } else if (rawTx.nLockTime) {
366 nSequence = std::numeric_limits<uint32_t>::max() - 1;
367 } else {
368 nSequence = std::numeric_limits<uint32_t>::max();
371 // set the sequence number if passed in the parameters object
372 const UniValue& sequenceObj = find_value(o, "sequence");
373 if (sequenceObj.isNum()) {
374 int64_t seqNr64 = sequenceObj.get_int64();
375 if (seqNr64 < 0 || seqNr64 > std::numeric_limits<uint32_t>::max()) {
376 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, sequence number is out of range");
377 } else {
378 nSequence = (uint32_t)seqNr64;
382 CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence);
384 rawTx.vin.push_back(in);
387 std::set<CTxDestination> destinations;
388 std::vector<std::string> addrList = sendTo.getKeys();
389 for (const std::string& name_ : addrList) {
391 if (name_ == "data") {
392 std::vector<unsigned char> data = ParseHexV(sendTo[name_].getValStr(),"Data");
394 CTxOut out(0, CScript() << OP_RETURN << data);
395 rawTx.vout.push_back(out);
396 } else {
397 CTxDestination destination = DecodeDestination(name_);
398 if (!IsValidDestination(destination)) {
399 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Bitcoin address: ") + name_);
402 if (!destinations.insert(destination).second) {
403 throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + name_);
406 CScript scriptPubKey = GetScriptForDestination(destination);
407 CAmount nAmount = AmountFromValue(sendTo[name_]);
409 CTxOut out(nAmount, scriptPubKey);
410 rawTx.vout.push_back(out);
414 if (!request.params[3].isNull() && rbfOptIn != SignalsOptInRBF(rawTx)) {
415 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter combination: Sequence number(s) contradict replaceable option");
418 return EncodeHexTx(rawTx);
421 UniValue decoderawtransaction(const JSONRPCRequest& request)
423 if (request.fHelp || request.params.size() != 1)
424 throw std::runtime_error(
425 "decoderawtransaction \"hexstring\"\n"
426 "\nReturn a JSON object representing the serialized, hex-encoded transaction.\n"
428 "\nArguments:\n"
429 "1. \"hexstring\" (string, required) The transaction hex string\n"
431 "\nResult:\n"
432 "{\n"
433 " \"txid\" : \"id\", (string) The transaction id\n"
434 " \"hash\" : \"id\", (string) The transaction hash (differs from txid for witness transactions)\n"
435 " \"size\" : n, (numeric) The transaction size\n"
436 " \"vsize\" : n, (numeric) The virtual transaction size (differs from size for witness transactions)\n"
437 " \"version\" : n, (numeric) The version\n"
438 " \"locktime\" : ttt, (numeric) The lock time\n"
439 " \"vin\" : [ (array of json objects)\n"
440 " {\n"
441 " \"txid\": \"id\", (string) The transaction id\n"
442 " \"vout\": n, (numeric) The output number\n"
443 " \"scriptSig\": { (json object) The script\n"
444 " \"asm\": \"asm\", (string) asm\n"
445 " \"hex\": \"hex\" (string) hex\n"
446 " },\n"
447 " \"txinwitness\": [\"hex\", ...] (array of string) hex-encoded witness data (if any)\n"
448 " \"sequence\": n (numeric) The script sequence number\n"
449 " }\n"
450 " ,...\n"
451 " ],\n"
452 " \"vout\" : [ (array of json objects)\n"
453 " {\n"
454 " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n"
455 " \"n\" : n, (numeric) index\n"
456 " \"scriptPubKey\" : { (json object)\n"
457 " \"asm\" : \"asm\", (string) the asm\n"
458 " \"hex\" : \"hex\", (string) the hex\n"
459 " \"reqSigs\" : n, (numeric) The required sigs\n"
460 " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
461 " \"addresses\" : [ (json array of string)\n"
462 " \"12tvKAXCxZjSmdNbao16dKXC8tRWfcF5oc\" (string) bitcoin address\n"
463 " ,...\n"
464 " ]\n"
465 " }\n"
466 " }\n"
467 " ,...\n"
468 " ],\n"
469 "}\n"
471 "\nExamples:\n"
472 + HelpExampleCli("decoderawtransaction", "\"hexstring\"")
473 + HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
476 LOCK(cs_main);
477 RPCTypeCheck(request.params, {UniValue::VSTR});
479 CMutableTransaction mtx;
481 if (!DecodeHexTx(mtx, request.params[0].get_str(), true))
482 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
484 UniValue result(UniValue::VOBJ);
485 TxToUniv(CTransaction(std::move(mtx)), uint256(), result, false);
487 return result;
490 UniValue decodescript(const JSONRPCRequest& request)
492 if (request.fHelp || request.params.size() != 1)
493 throw std::runtime_error(
494 "decodescript \"hexstring\"\n"
495 "\nDecode a hex-encoded script.\n"
496 "\nArguments:\n"
497 "1. \"hexstring\" (string) the hex encoded script\n"
498 "\nResult:\n"
499 "{\n"
500 " \"asm\":\"asm\", (string) Script public key\n"
501 " \"hex\":\"hex\", (string) hex encoded public key\n"
502 " \"type\":\"type\", (string) The output type\n"
503 " \"reqSigs\": n, (numeric) The required signatures\n"
504 " \"addresses\": [ (json array of string)\n"
505 " \"address\" (string) bitcoin address\n"
506 " ,...\n"
507 " ],\n"
508 " \"p2sh\",\"address\" (string) address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH).\n"
509 "}\n"
510 "\nExamples:\n"
511 + HelpExampleCli("decodescript", "\"hexstring\"")
512 + HelpExampleRpc("decodescript", "\"hexstring\"")
515 RPCTypeCheck(request.params, {UniValue::VSTR});
517 UniValue r(UniValue::VOBJ);
518 CScript script;
519 if (request.params[0].get_str().size() > 0){
520 std::vector<unsigned char> scriptData(ParseHexV(request.params[0], "argument"));
521 script = CScript(scriptData.begin(), scriptData.end());
522 } else {
523 // Empty scripts are valid
525 ScriptPubKeyToUniv(script, r, false);
527 UniValue type;
528 type = find_value(r, "type");
530 if (type.isStr() && type.get_str() != "scripthash") {
531 // P2SH cannot be wrapped in a P2SH. If this script is already a P2SH,
532 // don't return the address for a P2SH of the P2SH.
533 r.push_back(Pair("p2sh", EncodeDestination(CScriptID(script))));
536 return r;
539 /** Pushes a JSON object for script verification or signing errors to vErrorsRet. */
540 static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std::string& strMessage)
542 UniValue entry(UniValue::VOBJ);
543 entry.push_back(Pair("txid", txin.prevout.hash.ToString()));
544 entry.push_back(Pair("vout", (uint64_t)txin.prevout.n));
545 UniValue witness(UniValue::VARR);
546 for (unsigned int i = 0; i < txin.scriptWitness.stack.size(); i++) {
547 witness.push_back(HexStr(txin.scriptWitness.stack[i].begin(), txin.scriptWitness.stack[i].end()));
549 entry.push_back(Pair("witness", witness));
550 entry.push_back(Pair("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
551 entry.push_back(Pair("sequence", (uint64_t)txin.nSequence));
552 entry.push_back(Pair("error", strMessage));
553 vErrorsRet.push_back(entry);
556 UniValue combinerawtransaction(const JSONRPCRequest& request)
559 if (request.fHelp || request.params.size() != 1)
560 throw std::runtime_error(
561 "combinerawtransaction [\"hexstring\",...]\n"
562 "\nCombine multiple partially signed transactions into one transaction.\n"
563 "The combined transaction may be another partially signed transaction or a \n"
564 "fully signed transaction."
566 "\nArguments:\n"
567 "1. \"txs\" (string) A json array of hex strings of partially signed transactions\n"
568 " [\n"
569 " \"hexstring\" (string) A transaction hash\n"
570 " ,...\n"
571 " ]\n"
573 "\nResult:\n"
574 "\"hex\" (string) The hex-encoded raw transaction with signature(s)\n"
576 "\nExamples:\n"
577 + HelpExampleCli("combinerawtransaction", "[\"myhex1\", \"myhex2\", \"myhex3\"]")
581 UniValue txs = request.params[0].get_array();
582 std::vector<CMutableTransaction> txVariants(txs.size());
584 for (unsigned int idx = 0; idx < txs.size(); idx++) {
585 if (!DecodeHexTx(txVariants[idx], txs[idx].get_str(), true)) {
586 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed for tx %d", idx));
590 if (txVariants.empty()) {
591 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transactions");
594 // mergedTx will end up with all the signatures; it
595 // starts as a clone of the rawtx:
596 CMutableTransaction mergedTx(txVariants[0]);
598 // Fetch previous transactions (inputs):
599 CCoinsView viewDummy;
600 CCoinsViewCache view(&viewDummy);
602 LOCK(cs_main);
603 LOCK(mempool.cs);
604 CCoinsViewCache &viewChain = *pcoinsTip;
605 CCoinsViewMemPool viewMempool(&viewChain, mempool);
606 view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
608 for (const CTxIn& txin : mergedTx.vin) {
609 view.AccessCoin(txin.prevout); // Load entries from viewChain into view; can fail.
612 view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
615 // Use CTransaction for the constant parts of the
616 // transaction to avoid rehashing.
617 const CTransaction txConst(mergedTx);
618 // Sign what we can:
619 for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
620 CTxIn& txin = mergedTx.vin[i];
621 const Coin& coin = view.AccessCoin(txin.prevout);
622 if (coin.IsSpent()) {
623 throw JSONRPCError(RPC_VERIFY_ERROR, "Input not found or already spent");
625 const CScript& prevPubKey = coin.out.scriptPubKey;
626 const CAmount& amount = coin.out.nValue;
628 SignatureData sigdata;
630 // ... and merge in other signatures:
631 for (const CMutableTransaction& txv : txVariants) {
632 if (txv.vin.size() > i) {
633 sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(txv, i));
637 UpdateTransaction(mergedTx, i, sigdata);
640 return EncodeHexTx(mergedTx);
643 UniValue signrawtransaction(const JSONRPCRequest& request)
645 #ifdef ENABLE_WALLET
646 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
647 #endif
649 if (request.fHelp || request.params.size() < 1 || request.params.size() > 4)
650 throw std::runtime_error(
651 "signrawtransaction \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] [\"privatekey1\",...] sighashtype )\n"
652 "\nSign inputs for raw transaction (serialized, hex-encoded).\n"
653 "The second optional argument (may be null) is an array of previous transaction outputs that\n"
654 "this transaction depends on but may not yet be in the block chain.\n"
655 "The third optional argument (may be null) is an array of base58-encoded private\n"
656 "keys that, if given, will be the only keys used to sign the transaction.\n"
657 #ifdef ENABLE_WALLET
658 + HelpRequiringPassphrase(pwallet) + "\n"
659 #endif
661 "\nArguments:\n"
662 "1. \"hexstring\" (string, required) The transaction hex string\n"
663 "2. \"prevtxs\" (string, optional) An json array of previous dependent transaction outputs\n"
664 " [ (json array of json objects, or 'null' if none provided)\n"
665 " {\n"
666 " \"txid\":\"id\", (string, required) The transaction id\n"
667 " \"vout\":n, (numeric, required) The output number\n"
668 " \"scriptPubKey\": \"hex\", (string, required) script key\n"
669 " \"redeemScript\": \"hex\", (string, required for P2SH or P2WSH) redeem script\n"
670 " \"amount\": value (numeric, required) The amount spent\n"
671 " }\n"
672 " ,...\n"
673 " ]\n"
674 "3. \"privkeys\" (string, optional) A json array of base58-encoded private keys for signing\n"
675 " [ (json array of strings, or 'null' if none provided)\n"
676 " \"privatekey\" (string) private key in base58-encoding\n"
677 " ,...\n"
678 " ]\n"
679 "4. \"sighashtype\" (string, optional, default=ALL) The signature hash type. Must be one of\n"
680 " \"ALL\"\n"
681 " \"NONE\"\n"
682 " \"SINGLE\"\n"
683 " \"ALL|ANYONECANPAY\"\n"
684 " \"NONE|ANYONECANPAY\"\n"
685 " \"SINGLE|ANYONECANPAY\"\n"
687 "\nResult:\n"
688 "{\n"
689 " \"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n"
690 " \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n"
691 " \"errors\" : [ (json array of objects) Script verification errors (if there are any)\n"
692 " {\n"
693 " \"txid\" : \"hash\", (string) The hash of the referenced, previous transaction\n"
694 " \"vout\" : n, (numeric) The index of the output to spent and used as input\n"
695 " \"scriptSig\" : \"hex\", (string) The hex-encoded signature script\n"
696 " \"sequence\" : n, (numeric) Script sequence number\n"
697 " \"error\" : \"text\" (string) Verification or signing error related to the input\n"
698 " }\n"
699 " ,...\n"
700 " ]\n"
701 "}\n"
703 "\nExamples:\n"
704 + HelpExampleCli("signrawtransaction", "\"myhex\"")
705 + HelpExampleRpc("signrawtransaction", "\"myhex\"")
708 ObserveSafeMode();
709 #ifdef ENABLE_WALLET
710 LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : nullptr);
711 #else
712 LOCK(cs_main);
713 #endif
714 RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VARR, UniValue::VSTR}, true);
716 CMutableTransaction mtx;
717 if (!DecodeHexTx(mtx, request.params[0].get_str(), true))
718 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
720 // Fetch previous transactions (inputs):
721 CCoinsView viewDummy;
722 CCoinsViewCache view(&viewDummy);
724 LOCK(mempool.cs);
725 CCoinsViewCache &viewChain = *pcoinsTip;
726 CCoinsViewMemPool viewMempool(&viewChain, mempool);
727 view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
729 for (const CTxIn& txin : mtx.vin) {
730 view.AccessCoin(txin.prevout); // Load entries from viewChain into view; can fail.
733 view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
736 bool fGivenKeys = false;
737 CBasicKeyStore tempKeystore;
738 if (!request.params[2].isNull()) {
739 fGivenKeys = true;
740 UniValue keys = request.params[2].get_array();
741 for (unsigned int idx = 0; idx < keys.size(); idx++) {
742 UniValue k = keys[idx];
743 CBitcoinSecret vchSecret;
744 bool fGood = vchSecret.SetString(k.get_str());
745 if (!fGood)
746 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
747 CKey key = vchSecret.GetKey();
748 if (!key.IsValid())
749 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
750 tempKeystore.AddKey(key);
753 #ifdef ENABLE_WALLET
754 else if (pwallet) {
755 EnsureWalletIsUnlocked(pwallet);
757 #endif
759 // Add previous txouts given in the RPC call:
760 if (!request.params[1].isNull()) {
761 UniValue prevTxs = request.params[1].get_array();
762 for (unsigned int idx = 0; idx < prevTxs.size(); idx++) {
763 const UniValue& p = prevTxs[idx];
764 if (!p.isObject())
765 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}");
767 UniValue prevOut = p.get_obj();
769 RPCTypeCheckObj(prevOut,
771 {"txid", UniValueType(UniValue::VSTR)},
772 {"vout", UniValueType(UniValue::VNUM)},
773 {"scriptPubKey", UniValueType(UniValue::VSTR)},
776 uint256 txid = ParseHashO(prevOut, "txid");
778 int nOut = find_value(prevOut, "vout").get_int();
779 if (nOut < 0)
780 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout must be positive");
782 COutPoint out(txid, nOut);
783 std::vector<unsigned char> pkData(ParseHexO(prevOut, "scriptPubKey"));
784 CScript scriptPubKey(pkData.begin(), pkData.end());
787 const Coin& coin = view.AccessCoin(out);
788 if (!coin.IsSpent() && coin.out.scriptPubKey != scriptPubKey) {
789 std::string err("Previous output scriptPubKey mismatch:\n");
790 err = err + ScriptToAsmStr(coin.out.scriptPubKey) + "\nvs:\n"+
791 ScriptToAsmStr(scriptPubKey);
792 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err);
794 Coin newcoin;
795 newcoin.out.scriptPubKey = scriptPubKey;
796 newcoin.out.nValue = 0;
797 if (prevOut.exists("amount")) {
798 newcoin.out.nValue = AmountFromValue(find_value(prevOut, "amount"));
800 newcoin.nHeight = 1;
801 view.AddCoin(out, std::move(newcoin), true);
804 // if redeemScript given and not using the local wallet (private keys
805 // given), add redeemScript to the tempKeystore so it can be signed:
806 if (fGivenKeys && (scriptPubKey.IsPayToScriptHash() || scriptPubKey.IsPayToWitnessScriptHash())) {
807 RPCTypeCheckObj(prevOut,
809 {"txid", UniValueType(UniValue::VSTR)},
810 {"vout", UniValueType(UniValue::VNUM)},
811 {"scriptPubKey", UniValueType(UniValue::VSTR)},
812 {"redeemScript", UniValueType(UniValue::VSTR)},
814 UniValue v = find_value(prevOut, "redeemScript");
815 if (!v.isNull()) {
816 std::vector<unsigned char> rsData(ParseHexV(v, "redeemScript"));
817 CScript redeemScript(rsData.begin(), rsData.end());
818 tempKeystore.AddCScript(redeemScript);
824 #ifdef ENABLE_WALLET
825 const CKeyStore& keystore = ((fGivenKeys || !pwallet) ? tempKeystore : *pwallet);
826 #else
827 const CKeyStore& keystore = tempKeystore;
828 #endif
830 int nHashType = SIGHASH_ALL;
831 if (!request.params[3].isNull()) {
832 static std::map<std::string, int> mapSigHashValues = {
833 {std::string("ALL"), int(SIGHASH_ALL)},
834 {std::string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY)},
835 {std::string("NONE"), int(SIGHASH_NONE)},
836 {std::string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY)},
837 {std::string("SINGLE"), int(SIGHASH_SINGLE)},
838 {std::string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)},
840 std::string strHashType = request.params[3].get_str();
841 if (mapSigHashValues.count(strHashType))
842 nHashType = mapSigHashValues[strHashType];
843 else
844 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param");
847 bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
849 // Script verification errors
850 UniValue vErrors(UniValue::VARR);
852 // Use CTransaction for the constant parts of the
853 // transaction to avoid rehashing.
854 const CTransaction txConst(mtx);
855 // Sign what we can:
856 for (unsigned int i = 0; i < mtx.vin.size(); i++) {
857 CTxIn& txin = mtx.vin[i];
858 const Coin& coin = view.AccessCoin(txin.prevout);
859 if (coin.IsSpent()) {
860 TxInErrorToJSON(txin, vErrors, "Input not found or already spent");
861 continue;
863 const CScript& prevPubKey = coin.out.scriptPubKey;
864 const CAmount& amount = coin.out.nValue;
866 SignatureData sigdata;
867 // Only sign SIGHASH_SINGLE if there's a corresponding output:
868 if (!fHashSingle || (i < mtx.vout.size()))
869 ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mtx, i, amount, nHashType), prevPubKey, sigdata);
870 sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(mtx, i));
872 UpdateTransaction(mtx, i, sigdata);
874 ScriptError serror = SCRIPT_ERR_OK;
875 if (!VerifyScript(txin.scriptSig, prevPubKey, &txin.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount), &serror)) {
876 if (serror == SCRIPT_ERR_INVALID_STACK_OPERATION) {
877 // Unable to sign input and verification failed (possible attempt to partially sign).
878 TxInErrorToJSON(txin, vErrors, "Unable to sign input, invalid stack size (possibly missing key)");
879 } else {
880 TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror));
884 bool fComplete = vErrors.empty();
886 UniValue result(UniValue::VOBJ);
887 result.push_back(Pair("hex", EncodeHexTx(mtx)));
888 result.push_back(Pair("complete", fComplete));
889 if (!vErrors.empty()) {
890 result.push_back(Pair("errors", vErrors));
893 return result;
896 UniValue sendrawtransaction(const JSONRPCRequest& request)
898 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
899 throw std::runtime_error(
900 "sendrawtransaction \"hexstring\" ( allowhighfees )\n"
901 "\nSubmits raw transaction (serialized, hex-encoded) to local node and network.\n"
902 "\nAlso see createrawtransaction and signrawtransaction calls.\n"
903 "\nArguments:\n"
904 "1. \"hexstring\" (string, required) The hex string of the raw transaction)\n"
905 "2. allowhighfees (boolean, optional, default=false) Allow high fees\n"
906 "\nResult:\n"
907 "\"hex\" (string) The transaction hash in hex\n"
908 "\nExamples:\n"
909 "\nCreate a transaction\n"
910 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") +
911 "Sign the transaction, and get back the hex\n"
912 + HelpExampleCli("signrawtransaction", "\"myhex\"") +
913 "\nSend the transaction (signed hex)\n"
914 + HelpExampleCli("sendrawtransaction", "\"signedhex\"") +
915 "\nAs a json rpc call\n"
916 + HelpExampleRpc("sendrawtransaction", "\"signedhex\"")
919 ObserveSafeMode();
920 LOCK(cs_main);
921 RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL});
923 // parse hex string from parameter
924 CMutableTransaction mtx;
925 if (!DecodeHexTx(mtx, request.params[0].get_str()))
926 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
927 CTransactionRef tx(MakeTransactionRef(std::move(mtx)));
928 const uint256& hashTx = tx->GetHash();
930 CAmount nMaxRawTxFee = maxTxFee;
931 if (!request.params[1].isNull() && request.params[1].get_bool())
932 nMaxRawTxFee = 0;
934 CCoinsViewCache &view = *pcoinsTip;
935 bool fHaveChain = false;
936 for (size_t o = 0; !fHaveChain && o < tx->vout.size(); o++) {
937 const Coin& existingCoin = view.AccessCoin(COutPoint(hashTx, o));
938 fHaveChain = !existingCoin.IsSpent();
940 bool fHaveMempool = mempool.exists(hashTx);
941 if (!fHaveMempool && !fHaveChain) {
942 // push to local node and sync with wallets
943 CValidationState state;
944 bool fMissingInputs;
945 if (!AcceptToMemoryPool(mempool, state, std::move(tx), &fMissingInputs,
946 nullptr /* plTxnReplaced */, false /* bypass_limits */, nMaxRawTxFee)) {
947 if (state.IsInvalid()) {
948 throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
949 } else {
950 if (fMissingInputs) {
951 throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs");
953 throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason());
956 } else if (fHaveChain) {
957 throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain");
959 if(!g_connman)
960 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
962 CInv inv(MSG_TX, hashTx);
963 g_connman->ForEachNode([&inv](CNode* pnode)
965 pnode->PushInventory(inv);
967 return hashTx.GetHex();
970 static const CRPCCommand commands[] =
971 { // category name actor (function) argNames
972 // --------------------- ------------------------ ----------------------- ----------
973 { "rawtransactions", "getrawtransaction", &getrawtransaction, {"txid","verbose"} },
974 { "rawtransactions", "createrawtransaction", &createrawtransaction, {"inputs","outputs","locktime","replaceable"} },
975 { "rawtransactions", "decoderawtransaction", &decoderawtransaction, {"hexstring"} },
976 { "rawtransactions", "decodescript", &decodescript, {"hexstring"} },
977 { "rawtransactions", "sendrawtransaction", &sendrawtransaction, {"hexstring","allowhighfees"} },
978 { "rawtransactions", "combinerawtransaction", &combinerawtransaction, {"txs"} },
979 { "rawtransactions", "signrawtransaction", &signrawtransaction, {"hexstring","prevtxs","privkeys","sighashtype"} }, /* uses wallet if enabled */
981 { "blockchain", "gettxoutproof", &gettxoutproof, {"txids", "blockhash"} },
982 { "blockchain", "verifytxoutproof", &verifytxoutproof, {"proof"} },
985 void RegisterRawTransactionRPCCommands(CRPCTable &t)
987 for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
988 t.appendCommand(commands[vcidx].name, &commands[vcidx]);