refactor: Move GetDifficulty out of `rpc/server.h`
[bitcoinplatinum.git] / src / rpc / rawtransaction.cpp
blob696f1bd781092cef2d8c5739e26cc3c56a39dd6c
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 "primitives/transaction.h"
18 #include "rpc/server.h"
19 #include "script/script.h"
20 #include "script/script_error.h"
21 #include "script/sign.h"
22 #include "script/standard.h"
23 #include "txmempool.h"
24 #include "uint256.h"
25 #include "utilstrencodings.h"
26 #ifdef ENABLE_WALLET
27 #include "wallet/rpcwallet.h"
28 #include "wallet/wallet.h"
29 #endif
31 #include <stdint.h>
33 #include <boost/assign/list_of.hpp>
35 #include <univalue.h>
37 void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex)
39 txnouttype type;
40 std::vector<CTxDestination> addresses;
41 int nRequired;
43 out.push_back(Pair("asm", ScriptToAsmStr(scriptPubKey)));
44 if (fIncludeHex)
45 out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
47 if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) {
48 out.push_back(Pair("type", GetTxnOutputType(type)));
49 return;
52 out.push_back(Pair("reqSigs", nRequired));
53 out.push_back(Pair("type", GetTxnOutputType(type)));
55 UniValue a(UniValue::VARR);
56 BOOST_FOREACH(const CTxDestination& addr, addresses)
57 a.push_back(CBitcoinAddress(addr).ToString());
58 out.push_back(Pair("addresses", a));
61 void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
63 entry.push_back(Pair("txid", tx.GetHash().GetHex()));
64 entry.push_back(Pair("hash", tx.GetWitnessHash().GetHex()));
65 entry.push_back(Pair("size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION)));
66 entry.push_back(Pair("vsize", (int)::GetVirtualTransactionSize(tx)));
67 entry.push_back(Pair("version", tx.nVersion));
68 entry.push_back(Pair("locktime", (int64_t)tx.nLockTime));
70 UniValue vin(UniValue::VARR);
71 for (unsigned int i = 0; i < tx.vin.size(); i++) {
72 const CTxIn& txin = tx.vin[i];
73 UniValue in(UniValue::VOBJ);
74 if (tx.IsCoinBase())
75 in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
76 else {
77 in.push_back(Pair("txid", txin.prevout.hash.GetHex()));
78 in.push_back(Pair("vout", (int64_t)txin.prevout.n));
79 UniValue o(UniValue::VOBJ);
80 o.push_back(Pair("asm", ScriptToAsmStr(txin.scriptSig, true)));
81 o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
82 in.push_back(Pair("scriptSig", o));
84 if (tx.HasWitness()) {
85 UniValue txinwitness(UniValue::VARR);
86 for (unsigned int j = 0; j < tx.vin[i].scriptWitness.stack.size(); j++) {
87 std::vector<unsigned char> item = tx.vin[i].scriptWitness.stack[j];
88 txinwitness.push_back(HexStr(item.begin(), item.end()));
90 in.push_back(Pair("txinwitness", txinwitness));
92 in.push_back(Pair("sequence", (int64_t)txin.nSequence));
93 vin.push_back(in);
95 entry.push_back(Pair("vin", vin));
96 UniValue vout(UniValue::VARR);
97 for (unsigned int i = 0; i < tx.vout.size(); i++) {
98 const CTxOut& txout = tx.vout[i];
99 UniValue out(UniValue::VOBJ);
100 out.push_back(Pair("value", ValueFromAmount(txout.nValue)));
101 out.push_back(Pair("n", (int64_t)i));
102 UniValue o(UniValue::VOBJ);
103 ScriptPubKeyToJSON(txout.scriptPubKey, o, true);
104 out.push_back(Pair("scriptPubKey", o));
105 vout.push_back(out);
107 entry.push_back(Pair("vout", vout));
109 if (!hashBlock.IsNull()) {
110 entry.push_back(Pair("blockhash", hashBlock.GetHex()));
111 BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
112 if (mi != mapBlockIndex.end() && (*mi).second) {
113 CBlockIndex* pindex = (*mi).second;
114 if (chainActive.Contains(pindex)) {
115 entry.push_back(Pair("confirmations", 1 + chainActive.Height() - pindex->nHeight));
116 entry.push_back(Pair("time", pindex->GetBlockTime()));
117 entry.push_back(Pair("blocktime", pindex->GetBlockTime()));
119 else
120 entry.push_back(Pair("confirmations", 0));
125 UniValue getrawtransaction(const JSONRPCRequest& request)
127 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
128 throw std::runtime_error(
129 "getrawtransaction \"txid\" ( verbose )\n"
131 "\nNOTE: By default this function only works for mempool transactions. If the -txindex option is\n"
132 "enabled, it also works for blockchain transactions.\n"
133 "DEPRECATED: for now, it also works for transactions with unspent outputs.\n"
135 "\nReturn the raw transaction data.\n"
136 "\nIf verbose is 'true', returns an Object with information about 'txid'.\n"
137 "If verbose is 'false' or omitted, returns a string that is serialized, hex-encoded data for 'txid'.\n"
139 "\nArguments:\n"
140 "1. \"txid\" (string, required) The transaction id\n"
141 "2. verbose (bool, optional, default=false) If false, return a string, otherwise return a json object\n"
143 "\nResult (if verbose is not set or set to false):\n"
144 "\"data\" (string) The serialized, hex-encoded data for 'txid'\n"
146 "\nResult (if verbose is set to true):\n"
147 "{\n"
148 " \"hex\" : \"data\", (string) The serialized, hex-encoded data for 'txid'\n"
149 " \"txid\" : \"id\", (string) The transaction id (same as provided)\n"
150 " \"hash\" : \"id\", (string) The transaction hash (differs from txid for witness transactions)\n"
151 " \"size\" : n, (numeric) The serialized transaction size\n"
152 " \"vsize\" : n, (numeric) The virtual transaction size (differs from size for witness transactions)\n"
153 " \"version\" : n, (numeric) The version\n"
154 " \"locktime\" : ttt, (numeric) The lock time\n"
155 " \"vin\" : [ (array of json objects)\n"
156 " {\n"
157 " \"txid\": \"id\", (string) The transaction id\n"
158 " \"vout\": n, (numeric) \n"
159 " \"scriptSig\": { (json object) The script\n"
160 " \"asm\": \"asm\", (string) asm\n"
161 " \"hex\": \"hex\" (string) hex\n"
162 " },\n"
163 " \"sequence\": n (numeric) The script sequence number\n"
164 " \"txinwitness\": [\"hex\", ...] (array of string) hex-encoded witness data (if any)\n"
165 " }\n"
166 " ,...\n"
167 " ],\n"
168 " \"vout\" : [ (array of json objects)\n"
169 " {\n"
170 " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n"
171 " \"n\" : n, (numeric) index\n"
172 " \"scriptPubKey\" : { (json object)\n"
173 " \"asm\" : \"asm\", (string) the asm\n"
174 " \"hex\" : \"hex\", (string) the hex\n"
175 " \"reqSigs\" : n, (numeric) The required sigs\n"
176 " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
177 " \"addresses\" : [ (json array of string)\n"
178 " \"address\" (string) bitcoin address\n"
179 " ,...\n"
180 " ]\n"
181 " }\n"
182 " }\n"
183 " ,...\n"
184 " ],\n"
185 " \"blockhash\" : \"hash\", (string) the block hash\n"
186 " \"confirmations\" : n, (numeric) The confirmations\n"
187 " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT)\n"
188 " \"blocktime\" : ttt (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
189 "}\n"
191 "\nExamples:\n"
192 + HelpExampleCli("getrawtransaction", "\"mytxid\"")
193 + HelpExampleCli("getrawtransaction", "\"mytxid\" true")
194 + HelpExampleRpc("getrawtransaction", "\"mytxid\", true")
197 LOCK(cs_main);
199 uint256 hash = ParseHashV(request.params[0], "parameter 1");
201 // Accept either a bool (true) or a num (>=1) to indicate verbose output.
202 bool fVerbose = false;
203 if (request.params.size() > 1) {
204 if (request.params[1].isNum()) {
205 if (request.params[1].get_int() != 0) {
206 fVerbose = true;
209 else if(request.params[1].isBool()) {
210 if(request.params[1].isTrue()) {
211 fVerbose = true;
214 else {
215 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid type provided. Verbose parameter must be a boolean.");
219 CTransactionRef tx;
220 uint256 hashBlock;
221 if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true))
222 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string(fTxIndex ? "No such mempool or blockchain transaction"
223 : "No such mempool transaction. Use -txindex to enable blockchain transaction queries") +
224 ". Use gettransaction for wallet transactions.");
226 std::string strHex = EncodeHexTx(*tx, RPCSerializationFlags());
228 if (!fVerbose)
229 return strHex;
231 UniValue result(UniValue::VOBJ);
232 result.push_back(Pair("hex", strHex));
233 TxToJSON(*tx, hashBlock, result);
234 return result;
237 UniValue gettxoutproof(const JSONRPCRequest& request)
239 if (request.fHelp || (request.params.size() != 1 && request.params.size() != 2))
240 throw std::runtime_error(
241 "gettxoutproof [\"txid\",...] ( blockhash )\n"
242 "\nReturns a hex-encoded proof that \"txid\" was included in a block.\n"
243 "\nNOTE: By default this function only works sometimes. This is when there is an\n"
244 "unspent output in the utxo for this transaction. To make it always work,\n"
245 "you need to maintain a transaction index, using the -txindex command line option or\n"
246 "specify the block in which the transaction is included manually (by blockhash).\n"
247 "\nArguments:\n"
248 "1. \"txids\" (string) A json array of txids to filter\n"
249 " [\n"
250 " \"txid\" (string) A transaction hash\n"
251 " ,...\n"
252 " ]\n"
253 "2. \"blockhash\" (string, optional) If specified, looks for txid in the block with this hash\n"
254 "\nResult:\n"
255 "\"data\" (string) A string that is a serialized, hex-encoded data for the proof.\n"
258 std::set<uint256> setTxids;
259 uint256 oneTxid;
260 UniValue txids = request.params[0].get_array();
261 for (unsigned int idx = 0; idx < txids.size(); idx++) {
262 const UniValue& txid = txids[idx];
263 if (txid.get_str().length() != 64 || !IsHex(txid.get_str()))
264 throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid txid ")+txid.get_str());
265 uint256 hash(uint256S(txid.get_str()));
266 if (setTxids.count(hash))
267 throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated txid: ")+txid.get_str());
268 setTxids.insert(hash);
269 oneTxid = hash;
272 LOCK(cs_main);
274 CBlockIndex* pblockindex = NULL;
276 uint256 hashBlock;
277 if (request.params.size() > 1)
279 hashBlock = uint256S(request.params[1].get_str());
280 if (!mapBlockIndex.count(hashBlock))
281 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
282 pblockindex = mapBlockIndex[hashBlock];
283 } else {
284 CCoins coins;
285 if (pcoinsTip->GetCoins(oneTxid, coins) && coins.nHeight > 0 && coins.nHeight <= chainActive.Height())
286 pblockindex = chainActive[coins.nHeight];
289 if (pblockindex == NULL)
291 CTransactionRef tx;
292 if (!GetTransaction(oneTxid, tx, Params().GetConsensus(), hashBlock, false) || hashBlock.IsNull())
293 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block");
294 if (!mapBlockIndex.count(hashBlock))
295 throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt");
296 pblockindex = mapBlockIndex[hashBlock];
299 CBlock block;
300 if(!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
301 throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
303 unsigned int ntxFound = 0;
304 for (const auto& tx : block.vtx)
305 if (setTxids.count(tx->GetHash()))
306 ntxFound++;
307 if (ntxFound != setTxids.size())
308 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "(Not all) transactions not found in specified block");
310 CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS);
311 CMerkleBlock mb(block, setTxids);
312 ssMB << mb;
313 std::string strHex = HexStr(ssMB.begin(), ssMB.end());
314 return strHex;
317 UniValue verifytxoutproof(const JSONRPCRequest& request)
319 if (request.fHelp || request.params.size() != 1)
320 throw std::runtime_error(
321 "verifytxoutproof \"proof\"\n"
322 "\nVerifies that a proof points to a transaction in a block, returning the transaction it commits to\n"
323 "and throwing an RPC error if the block is not in our best chain\n"
324 "\nArguments:\n"
325 "1. \"proof\" (string, required) The hex-encoded proof generated by gettxoutproof\n"
326 "\nResult:\n"
327 "[\"txid\"] (array, strings) The txid(s) which the proof commits to, or empty array if the proof is invalid\n"
330 CDataStream ssMB(ParseHexV(request.params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS);
331 CMerkleBlock merkleBlock;
332 ssMB >> merkleBlock;
334 UniValue res(UniValue::VARR);
336 std::vector<uint256> vMatch;
337 std::vector<unsigned int> vIndex;
338 if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) != merkleBlock.header.hashMerkleRoot)
339 return res;
341 LOCK(cs_main);
343 if (!mapBlockIndex.count(merkleBlock.header.GetHash()) || !chainActive.Contains(mapBlockIndex[merkleBlock.header.GetHash()]))
344 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain");
346 BOOST_FOREACH(const uint256& hash, vMatch)
347 res.push_back(hash.GetHex());
348 return res;
351 UniValue createrawtransaction(const JSONRPCRequest& request)
353 if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
354 throw std::runtime_error(
355 "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,\"data\":\"hex\",...} ( locktime )\n"
356 "\nCreate a transaction spending the given inputs and creating new outputs.\n"
357 "Outputs can be addresses or data.\n"
358 "Returns hex-encoded raw transaction.\n"
359 "Note that the transaction's inputs are not signed, and\n"
360 "it is not stored in the wallet or transmitted to the network.\n"
362 "\nArguments:\n"
363 "1. \"inputs\" (string, required) A json array of json objects\n"
364 " [\n"
365 " {\n"
366 " \"txid\":\"id\", (string, required) The transaction id\n"
367 " \"vout\":n, (numeric, required) The output number\n"
368 " \"sequence\":n (numeric, optional) The sequence number\n"
369 " } \n"
370 " ,...\n"
371 " ]\n"
372 "2. \"outputs\" (string, required) a json object with outputs\n"
373 " {\n"
374 " \"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"
375 " \"data\": \"hex\" (string, required) The key is \"data\", the value is hex encoded data\n"
376 " ,...\n"
377 " }\n"
378 "3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n"
379 "\nResult:\n"
380 "\"transaction\" (string) hex string of the transaction\n"
382 "\nExamples:\n"
383 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":0.01}\"")
384 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"data\\\":\\\"00010203\\\"}\"")
385 + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\"")
386 + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"data\\\":\\\"00010203\\\"}\"")
389 RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VARR)(UniValue::VOBJ)(UniValue::VNUM), true);
390 if (request.params[0].isNull() || request.params[1].isNull())
391 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, arguments 1 and 2 must be non-null");
393 UniValue inputs = request.params[0].get_array();
394 UniValue sendTo = request.params[1].get_obj();
396 CMutableTransaction rawTx;
398 if (request.params.size() > 2 && !request.params[2].isNull()) {
399 int64_t nLockTime = request.params[2].get_int64();
400 if (nLockTime < 0 || nLockTime > std::numeric_limits<uint32_t>::max())
401 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, locktime out of range");
402 rawTx.nLockTime = nLockTime;
405 for (unsigned int idx = 0; idx < inputs.size(); idx++) {
406 const UniValue& input = inputs[idx];
407 const UniValue& o = input.get_obj();
409 uint256 txid = ParseHashO(o, "txid");
411 const UniValue& vout_v = find_value(o, "vout");
412 if (!vout_v.isNum())
413 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");
414 int nOutput = vout_v.get_int();
415 if (nOutput < 0)
416 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
418 uint32_t nSequence = (rawTx.nLockTime ? std::numeric_limits<uint32_t>::max() - 1 : std::numeric_limits<uint32_t>::max());
420 // set the sequence number if passed in the parameters object
421 const UniValue& sequenceObj = find_value(o, "sequence");
422 if (sequenceObj.isNum()) {
423 int64_t seqNr64 = sequenceObj.get_int64();
424 if (seqNr64 < 0 || seqNr64 > std::numeric_limits<uint32_t>::max())
425 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, sequence number is out of range");
426 else
427 nSequence = (uint32_t)seqNr64;
430 CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence);
432 rawTx.vin.push_back(in);
435 std::set<CBitcoinAddress> setAddress;
436 std::vector<std::string> addrList = sendTo.getKeys();
437 BOOST_FOREACH(const std::string& name_, addrList) {
439 if (name_ == "data") {
440 std::vector<unsigned char> data = ParseHexV(sendTo[name_].getValStr(),"Data");
442 CTxOut out(0, CScript() << OP_RETURN << data);
443 rawTx.vout.push_back(out);
444 } else {
445 CBitcoinAddress address(name_);
446 if (!address.IsValid())
447 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Bitcoin address: ")+name_);
449 if (setAddress.count(address))
450 throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ")+name_);
451 setAddress.insert(address);
453 CScript scriptPubKey = GetScriptForDestination(address.Get());
454 CAmount nAmount = AmountFromValue(sendTo[name_]);
456 CTxOut out(nAmount, scriptPubKey);
457 rawTx.vout.push_back(out);
461 return EncodeHexTx(rawTx);
464 UniValue decoderawtransaction(const JSONRPCRequest& request)
466 if (request.fHelp || request.params.size() != 1)
467 throw std::runtime_error(
468 "decoderawtransaction \"hexstring\"\n"
469 "\nReturn a JSON object representing the serialized, hex-encoded transaction.\n"
471 "\nArguments:\n"
472 "1. \"hexstring\" (string, required) The transaction hex string\n"
474 "\nResult:\n"
475 "{\n"
476 " \"txid\" : \"id\", (string) The transaction id\n"
477 " \"hash\" : \"id\", (string) The transaction hash (differs from txid for witness transactions)\n"
478 " \"size\" : n, (numeric) The transaction size\n"
479 " \"vsize\" : n, (numeric) The virtual transaction size (differs from size for witness transactions)\n"
480 " \"version\" : n, (numeric) The version\n"
481 " \"locktime\" : ttt, (numeric) The lock time\n"
482 " \"vin\" : [ (array of json objects)\n"
483 " {\n"
484 " \"txid\": \"id\", (string) The transaction id\n"
485 " \"vout\": n, (numeric) The output number\n"
486 " \"scriptSig\": { (json object) The script\n"
487 " \"asm\": \"asm\", (string) asm\n"
488 " \"hex\": \"hex\" (string) hex\n"
489 " },\n"
490 " \"txinwitness\": [\"hex\", ...] (array of string) hex-encoded witness data (if any)\n"
491 " \"sequence\": n (numeric) The script sequence number\n"
492 " }\n"
493 " ,...\n"
494 " ],\n"
495 " \"vout\" : [ (array of json objects)\n"
496 " {\n"
497 " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n"
498 " \"n\" : n, (numeric) index\n"
499 " \"scriptPubKey\" : { (json object)\n"
500 " \"asm\" : \"asm\", (string) the asm\n"
501 " \"hex\" : \"hex\", (string) the hex\n"
502 " \"reqSigs\" : n, (numeric) The required sigs\n"
503 " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
504 " \"addresses\" : [ (json array of string)\n"
505 " \"12tvKAXCxZjSmdNbao16dKXC8tRWfcF5oc\" (string) bitcoin address\n"
506 " ,...\n"
507 " ]\n"
508 " }\n"
509 " }\n"
510 " ,...\n"
511 " ],\n"
512 "}\n"
514 "\nExamples:\n"
515 + HelpExampleCli("decoderawtransaction", "\"hexstring\"")
516 + HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
519 LOCK(cs_main);
520 RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR));
522 CMutableTransaction mtx;
524 if (!DecodeHexTx(mtx, request.params[0].get_str(), true))
525 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
527 UniValue result(UniValue::VOBJ);
528 TxToJSON(CTransaction(std::move(mtx)), uint256(), result);
530 return result;
533 UniValue decodescript(const JSONRPCRequest& request)
535 if (request.fHelp || request.params.size() != 1)
536 throw std::runtime_error(
537 "decodescript \"hexstring\"\n"
538 "\nDecode a hex-encoded script.\n"
539 "\nArguments:\n"
540 "1. \"hexstring\" (string) the hex encoded script\n"
541 "\nResult:\n"
542 "{\n"
543 " \"asm\":\"asm\", (string) Script public key\n"
544 " \"hex\":\"hex\", (string) hex encoded public key\n"
545 " \"type\":\"type\", (string) The output type\n"
546 " \"reqSigs\": n, (numeric) The required signatures\n"
547 " \"addresses\": [ (json array of string)\n"
548 " \"address\" (string) bitcoin address\n"
549 " ,...\n"
550 " ],\n"
551 " \"p2sh\",\"address\" (string) address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH).\n"
552 "}\n"
553 "\nExamples:\n"
554 + HelpExampleCli("decodescript", "\"hexstring\"")
555 + HelpExampleRpc("decodescript", "\"hexstring\"")
558 RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR));
560 UniValue r(UniValue::VOBJ);
561 CScript script;
562 if (request.params[0].get_str().size() > 0){
563 std::vector<unsigned char> scriptData(ParseHexV(request.params[0], "argument"));
564 script = CScript(scriptData.begin(), scriptData.end());
565 } else {
566 // Empty scripts are valid
568 ScriptPubKeyToJSON(script, r, false);
570 UniValue type;
571 type = find_value(r, "type");
573 if (type.isStr() && type.get_str() != "scripthash") {
574 // P2SH cannot be wrapped in a P2SH. If this script is already a P2SH,
575 // don't return the address for a P2SH of the P2SH.
576 r.push_back(Pair("p2sh", CBitcoinAddress(CScriptID(script)).ToString()));
579 return r;
582 /** Pushes a JSON object for script verification or signing errors to vErrorsRet. */
583 static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std::string& strMessage)
585 UniValue entry(UniValue::VOBJ);
586 entry.push_back(Pair("txid", txin.prevout.hash.ToString()));
587 entry.push_back(Pair("vout", (uint64_t)txin.prevout.n));
588 entry.push_back(Pair("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
589 entry.push_back(Pair("sequence", (uint64_t)txin.nSequence));
590 entry.push_back(Pair("error", strMessage));
591 vErrorsRet.push_back(entry);
594 UniValue signrawtransaction(const JSONRPCRequest& request)
596 #ifdef ENABLE_WALLET
597 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
598 #endif
600 if (request.fHelp || request.params.size() < 1 || request.params.size() > 4)
601 throw std::runtime_error(
602 "signrawtransaction \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] [\"privatekey1\",...] sighashtype )\n"
603 "\nSign inputs for raw transaction (serialized, hex-encoded).\n"
604 "The second optional argument (may be null) is an array of previous transaction outputs that\n"
605 "this transaction depends on but may not yet be in the block chain.\n"
606 "The third optional argument (may be null) is an array of base58-encoded private\n"
607 "keys that, if given, will be the only keys used to sign the transaction.\n"
608 #ifdef ENABLE_WALLET
609 + HelpRequiringPassphrase(pwallet) + "\n"
610 #endif
612 "\nArguments:\n"
613 "1. \"hexstring\" (string, required) The transaction hex string\n"
614 "2. \"prevtxs\" (string, optional) An json array of previous dependent transaction outputs\n"
615 " [ (json array of json objects, or 'null' if none provided)\n"
616 " {\n"
617 " \"txid\":\"id\", (string, required) The transaction id\n"
618 " \"vout\":n, (numeric, required) The output number\n"
619 " \"scriptPubKey\": \"hex\", (string, required) script key\n"
620 " \"redeemScript\": \"hex\", (string, required for P2SH or P2WSH) redeem script\n"
621 " \"amount\": value (numeric, required) The amount spent\n"
622 " }\n"
623 " ,...\n"
624 " ]\n"
625 "3. \"privkeys\" (string, optional) A json array of base58-encoded private keys for signing\n"
626 " [ (json array of strings, or 'null' if none provided)\n"
627 " \"privatekey\" (string) private key in base58-encoding\n"
628 " ,...\n"
629 " ]\n"
630 "4. \"sighashtype\" (string, optional, default=ALL) The signature hash type. Must be one of\n"
631 " \"ALL\"\n"
632 " \"NONE\"\n"
633 " \"SINGLE\"\n"
634 " \"ALL|ANYONECANPAY\"\n"
635 " \"NONE|ANYONECANPAY\"\n"
636 " \"SINGLE|ANYONECANPAY\"\n"
638 "\nResult:\n"
639 "{\n"
640 " \"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n"
641 " \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n"
642 " \"errors\" : [ (json array of objects) Script verification errors (if there are any)\n"
643 " {\n"
644 " \"txid\" : \"hash\", (string) The hash of the referenced, previous transaction\n"
645 " \"vout\" : n, (numeric) The index of the output to spent and used as input\n"
646 " \"scriptSig\" : \"hex\", (string) The hex-encoded signature script\n"
647 " \"sequence\" : n, (numeric) Script sequence number\n"
648 " \"error\" : \"text\" (string) Verification or signing error related to the input\n"
649 " }\n"
650 " ,...\n"
651 " ]\n"
652 "}\n"
654 "\nExamples:\n"
655 + HelpExampleCli("signrawtransaction", "\"myhex\"")
656 + HelpExampleRpc("signrawtransaction", "\"myhex\"")
659 #ifdef ENABLE_WALLET
660 LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : NULL);
661 #else
662 LOCK(cs_main);
663 #endif
664 RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR)(UniValue::VARR)(UniValue::VARR)(UniValue::VSTR), true);
666 std::vector<unsigned char> txData(ParseHexV(request.params[0], "argument 1"));
667 CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
668 std::vector<CMutableTransaction> txVariants;
669 while (!ssData.empty()) {
670 try {
671 CMutableTransaction tx;
672 ssData >> tx;
673 txVariants.push_back(tx);
675 catch (const std::exception&) {
676 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
680 if (txVariants.empty())
681 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transaction");
683 // mergedTx will end up with all the signatures; it
684 // starts as a clone of the rawtx:
685 CMutableTransaction mergedTx(txVariants[0]);
687 // Fetch previous transactions (inputs):
688 CCoinsView viewDummy;
689 CCoinsViewCache view(&viewDummy);
691 LOCK(mempool.cs);
692 CCoinsViewCache &viewChain = *pcoinsTip;
693 CCoinsViewMemPool viewMempool(&viewChain, mempool);
694 view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
696 BOOST_FOREACH(const CTxIn& txin, mergedTx.vin) {
697 const uint256& prevHash = txin.prevout.hash;
698 CCoins coins;
699 view.AccessCoins(prevHash); // this is certainly allowed to fail
702 view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
705 bool fGivenKeys = false;
706 CBasicKeyStore tempKeystore;
707 if (request.params.size() > 2 && !request.params[2].isNull()) {
708 fGivenKeys = true;
709 UniValue keys = request.params[2].get_array();
710 for (unsigned int idx = 0; idx < keys.size(); idx++) {
711 UniValue k = keys[idx];
712 CBitcoinSecret vchSecret;
713 bool fGood = vchSecret.SetString(k.get_str());
714 if (!fGood)
715 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
716 CKey key = vchSecret.GetKey();
717 if (!key.IsValid())
718 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
719 tempKeystore.AddKey(key);
722 #ifdef ENABLE_WALLET
723 else if (pwallet) {
724 EnsureWalletIsUnlocked(pwallet);
726 #endif
728 // Add previous txouts given in the RPC call:
729 if (request.params.size() > 1 && !request.params[1].isNull()) {
730 UniValue prevTxs = request.params[1].get_array();
731 for (unsigned int idx = 0; idx < prevTxs.size(); idx++) {
732 const UniValue& p = prevTxs[idx];
733 if (!p.isObject())
734 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}");
736 UniValue prevOut = p.get_obj();
738 RPCTypeCheckObj(prevOut,
740 {"txid", UniValueType(UniValue::VSTR)},
741 {"vout", UniValueType(UniValue::VNUM)},
742 {"scriptPubKey", UniValueType(UniValue::VSTR)},
745 uint256 txid = ParseHashO(prevOut, "txid");
747 int nOut = find_value(prevOut, "vout").get_int();
748 if (nOut < 0)
749 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout must be positive");
751 std::vector<unsigned char> pkData(ParseHexO(prevOut, "scriptPubKey"));
752 CScript scriptPubKey(pkData.begin(), pkData.end());
755 CCoinsModifier coins = view.ModifyCoins(txid);
756 if (coins->IsAvailable(nOut) && coins->vout[nOut].scriptPubKey != scriptPubKey) {
757 std::string err("Previous output scriptPubKey mismatch:\n");
758 err = err + ScriptToAsmStr(coins->vout[nOut].scriptPubKey) + "\nvs:\n"+
759 ScriptToAsmStr(scriptPubKey);
760 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err);
762 if ((unsigned int)nOut >= coins->vout.size())
763 coins->vout.resize(nOut+1);
764 coins->vout[nOut].scriptPubKey = scriptPubKey;
765 coins->vout[nOut].nValue = 0;
766 if (prevOut.exists("amount")) {
767 coins->vout[nOut].nValue = AmountFromValue(find_value(prevOut, "amount"));
771 // if redeemScript given and not using the local wallet (private keys
772 // given), add redeemScript to the tempKeystore so it can be signed:
773 if (fGivenKeys && (scriptPubKey.IsPayToScriptHash() || scriptPubKey.IsPayToWitnessScriptHash())) {
774 RPCTypeCheckObj(prevOut,
776 {"txid", UniValueType(UniValue::VSTR)},
777 {"vout", UniValueType(UniValue::VNUM)},
778 {"scriptPubKey", UniValueType(UniValue::VSTR)},
779 {"redeemScript", UniValueType(UniValue::VSTR)},
781 UniValue v = find_value(prevOut, "redeemScript");
782 if (!v.isNull()) {
783 std::vector<unsigned char> rsData(ParseHexV(v, "redeemScript"));
784 CScript redeemScript(rsData.begin(), rsData.end());
785 tempKeystore.AddCScript(redeemScript);
791 #ifdef ENABLE_WALLET
792 const CKeyStore& keystore = ((fGivenKeys || !pwallet) ? tempKeystore : *pwallet);
793 #else
794 const CKeyStore& keystore = tempKeystore;
795 #endif
797 int nHashType = SIGHASH_ALL;
798 if (request.params.size() > 3 && !request.params[3].isNull()) {
799 static std::map<std::string, int> mapSigHashValues =
800 boost::assign::map_list_of
801 (std::string("ALL"), int(SIGHASH_ALL))
802 (std::string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY))
803 (std::string("NONE"), int(SIGHASH_NONE))
804 (std::string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY))
805 (std::string("SINGLE"), int(SIGHASH_SINGLE))
806 (std::string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY))
808 std::string strHashType = request.params[3].get_str();
809 if (mapSigHashValues.count(strHashType))
810 nHashType = mapSigHashValues[strHashType];
811 else
812 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param");
815 bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
817 // Script verification errors
818 UniValue vErrors(UniValue::VARR);
820 // Use CTransaction for the constant parts of the
821 // transaction to avoid rehashing.
822 const CTransaction txConst(mergedTx);
823 // Sign what we can:
824 for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
825 CTxIn& txin = mergedTx.vin[i];
826 const CCoins* coins = view.AccessCoins(txin.prevout.hash);
827 if (coins == NULL || !coins->IsAvailable(txin.prevout.n)) {
828 TxInErrorToJSON(txin, vErrors, "Input not found or already spent");
829 continue;
831 const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey;
832 const CAmount& amount = coins->vout[txin.prevout.n].nValue;
834 SignatureData sigdata;
835 // Only sign SIGHASH_SINGLE if there's a corresponding output:
836 if (!fHashSingle || (i < mergedTx.vout.size()))
837 ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mergedTx, i, amount, nHashType), prevPubKey, sigdata);
839 // ... and merge in other signatures:
840 BOOST_FOREACH(const CMutableTransaction& txv, txVariants) {
841 if (txv.vin.size() > i) {
842 sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(txv, i));
846 UpdateTransaction(mergedTx, i, sigdata);
848 ScriptError serror = SCRIPT_ERR_OK;
849 if (!VerifyScript(txin.scriptSig, prevPubKey, &txin.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount), &serror)) {
850 TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror));
853 bool fComplete = vErrors.empty();
855 UniValue result(UniValue::VOBJ);
856 result.push_back(Pair("hex", EncodeHexTx(mergedTx)));
857 result.push_back(Pair("complete", fComplete));
858 if (!vErrors.empty()) {
859 result.push_back(Pair("errors", vErrors));
862 return result;
865 UniValue sendrawtransaction(const JSONRPCRequest& request)
867 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
868 throw std::runtime_error(
869 "sendrawtransaction \"hexstring\" ( allowhighfees )\n"
870 "\nSubmits raw transaction (serialized, hex-encoded) to local node and network.\n"
871 "\nAlso see createrawtransaction and signrawtransaction calls.\n"
872 "\nArguments:\n"
873 "1. \"hexstring\" (string, required) The hex string of the raw transaction)\n"
874 "2. allowhighfees (boolean, optional, default=false) Allow high fees\n"
875 "\nResult:\n"
876 "\"hex\" (string) The transaction hash in hex\n"
877 "\nExamples:\n"
878 "\nCreate a transaction\n"
879 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") +
880 "Sign the transaction, and get back the hex\n"
881 + HelpExampleCli("signrawtransaction", "\"myhex\"") +
882 "\nSend the transaction (signed hex)\n"
883 + HelpExampleCli("sendrawtransaction", "\"signedhex\"") +
884 "\nAs a json rpc call\n"
885 + HelpExampleRpc("sendrawtransaction", "\"signedhex\"")
888 LOCK(cs_main);
889 RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR)(UniValue::VBOOL));
891 // parse hex string from parameter
892 CMutableTransaction mtx;
893 if (!DecodeHexTx(mtx, request.params[0].get_str()))
894 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
895 CTransactionRef tx(MakeTransactionRef(std::move(mtx)));
896 const uint256& hashTx = tx->GetHash();
898 bool fLimitFree = true;
899 CAmount nMaxRawTxFee = maxTxFee;
900 if (request.params.size() > 1 && request.params[1].get_bool())
901 nMaxRawTxFee = 0;
903 CCoinsViewCache &view = *pcoinsTip;
904 const CCoins* existingCoins = view.AccessCoins(hashTx);
905 bool fHaveMempool = mempool.exists(hashTx);
906 bool fHaveChain = existingCoins && existingCoins->nHeight < 1000000000;
907 if (!fHaveMempool && !fHaveChain) {
908 // push to local node and sync with wallets
909 CValidationState state;
910 bool fMissingInputs;
911 if (!AcceptToMemoryPool(mempool, state, std::move(tx), fLimitFree, &fMissingInputs, NULL, false, nMaxRawTxFee)) {
912 if (state.IsInvalid()) {
913 throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
914 } else {
915 if (fMissingInputs) {
916 throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs");
918 throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason());
921 } else if (fHaveChain) {
922 throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain");
924 if(!g_connman)
925 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
927 CInv inv(MSG_TX, hashTx);
928 g_connman->ForEachNode([&inv](CNode* pnode)
930 pnode->PushInventory(inv);
932 return hashTx.GetHex();
935 static const CRPCCommand commands[] =
936 { // category name actor (function) okSafeMode
937 // --------------------- ------------------------ ----------------------- ----------
938 { "rawtransactions", "getrawtransaction", &getrawtransaction, true, {"txid","verbose"} },
939 { "rawtransactions", "createrawtransaction", &createrawtransaction, true, {"transactions","outputs","locktime"} },
940 { "rawtransactions", "decoderawtransaction", &decoderawtransaction, true, {"hexstring"} },
941 { "rawtransactions", "decodescript", &decodescript, true, {"hexstring"} },
942 { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false, {"hexstring","allowhighfees"} },
943 { "rawtransactions", "signrawtransaction", &signrawtransaction, false, {"hexstring","prevtxs","privkeys","sighashtype"} }, /* uses wallet if enabled */
945 { "blockchain", "gettxoutproof", &gettxoutproof, true, {"txids", "blockhash"} },
946 { "blockchain", "verifytxoutproof", &verifytxoutproof, true, {"proof"} },
949 void RegisterRawTransactionRPCCommands(CRPCTable &t)
951 for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
952 t.appendCommand(commands[vcidx].name, &commands[vcidx]);