Move CTxInWitness inside CTxIn
[bitcoinplatinum.git] / src / rpc / rawtransaction.cpp
blobb13aa4de34f07ee0108afddfb0849d1b3a1c70cb
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2015 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/wallet.h"
28 #endif
30 #include <stdint.h>
32 #include <boost/assign/list_of.hpp>
34 #include <univalue.h>
36 using namespace std;
38 void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex)
40 txnouttype type;
41 vector<CTxDestination> addresses;
42 int nRequired;
44 out.push_back(Pair("asm", ScriptToAsmStr(scriptPubKey)));
45 if (fIncludeHex)
46 out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
48 if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) {
49 out.push_back(Pair("type", GetTxnOutputType(type)));
50 return;
53 out.push_back(Pair("reqSigs", nRequired));
54 out.push_back(Pair("type", GetTxnOutputType(type)));
56 UniValue a(UniValue::VARR);
57 BOOST_FOREACH(const CTxDestination& addr, addresses)
58 a.push_back(CBitcoinAddress(addr).ToString());
59 out.push_back(Pair("addresses", a));
62 void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
64 entry.push_back(Pair("txid", tx.GetHash().GetHex()));
65 entry.push_back(Pair("hash", tx.GetWitnessHash().GetHex()));
66 entry.push_back(Pair("size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION)));
67 entry.push_back(Pair("vsize", (int)::GetVirtualTransactionSize(tx)));
68 entry.push_back(Pair("version", tx.nVersion));
69 entry.push_back(Pair("locktime", (int64_t)tx.nLockTime));
71 UniValue vin(UniValue::VARR);
72 for (unsigned int i = 0; i < tx.vin.size(); i++) {
73 const CTxIn& txin = tx.vin[i];
74 UniValue in(UniValue::VOBJ);
75 if (tx.IsCoinBase())
76 in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
77 else {
78 in.push_back(Pair("txid", txin.prevout.hash.GetHex()));
79 in.push_back(Pair("vout", (int64_t)txin.prevout.n));
80 UniValue o(UniValue::VOBJ);
81 o.push_back(Pair("asm", ScriptToAsmStr(txin.scriptSig, true)));
82 o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
83 in.push_back(Pair("scriptSig", o));
85 if (tx.HasWitness()) {
86 UniValue txinwitness(UniValue::VARR);
87 for (unsigned int j = 0; j < tx.vin[i].scriptWitness.stack.size(); j++) {
88 std::vector<unsigned char> item = tx.vin[i].scriptWitness.stack[j];
89 txinwitness.push_back(HexStr(item.begin(), item.end()));
91 in.push_back(Pair("txinwitness", txinwitness));
93 in.push_back(Pair("sequence", (int64_t)txin.nSequence));
94 vin.push_back(in);
96 entry.push_back(Pair("vin", vin));
97 UniValue vout(UniValue::VARR);
98 for (unsigned int i = 0; i < tx.vout.size(); i++) {
99 const CTxOut& txout = tx.vout[i];
100 UniValue out(UniValue::VOBJ);
101 out.push_back(Pair("value", ValueFromAmount(txout.nValue)));
102 out.push_back(Pair("n", (int64_t)i));
103 UniValue o(UniValue::VOBJ);
104 ScriptPubKeyToJSON(txout.scriptPubKey, o, true);
105 out.push_back(Pair("scriptPubKey", o));
106 vout.push_back(out);
108 entry.push_back(Pair("vout", vout));
110 if (!hashBlock.IsNull()) {
111 entry.push_back(Pair("blockhash", hashBlock.GetHex()));
112 BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
113 if (mi != mapBlockIndex.end() && (*mi).second) {
114 CBlockIndex* pindex = (*mi).second;
115 if (chainActive.Contains(pindex)) {
116 entry.push_back(Pair("confirmations", 1 + chainActive.Height() - pindex->nHeight));
117 entry.push_back(Pair("time", pindex->GetBlockTime()));
118 entry.push_back(Pair("blocktime", pindex->GetBlockTime()));
120 else
121 entry.push_back(Pair("confirmations", 0));
126 UniValue getrawtransaction(const JSONRPCRequest& request)
128 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
129 throw runtime_error(
130 "getrawtransaction \"txid\" ( verbose )\n"
131 "\nNOTE: By default this function only works sometimes. This is when the tx is in the mempool\n"
132 "or there is an unspent output in the utxo for this transaction. To make it always work,\n"
133 "you need to maintain a transaction index, using the -txindex command line option.\n"
134 "\nReturn the raw transaction data.\n"
135 "\nIf verbose is 'true', returns an Object with information about 'txid'.\n"
136 "If verbose is 'false' or omitted, returns a string that is serialized, hex-encoded data for 'txid'.\n"
138 "\nArguments:\n"
139 "1. \"txid\" (string, required) The transaction id\n"
140 "2. verbose (bool, optional, default=false) If true, return a string, other return a json object\n"
142 "\nResult (if verbose is not set or set to false):\n"
143 "\"data\" (string) The serialized, hex-encoded data for 'txid'\n"
145 "\nResult (if verbose is set to true):\n"
146 "{\n"
147 " \"hex\" : \"data\", (string) The serialized, hex-encoded data for 'txid'\n"
148 " \"txid\" : \"id\", (string) The transaction id (same as provided)\n"
149 " \"hash\" : \"id\", (string) The transaction hash (differs from txid for witness transactions)\n"
150 " \"size\" : n, (numeric) The serialized transaction size\n"
151 " \"vsize\" : n, (numeric) The virtual transaction size (differs from size for witness transactions)\n"
152 " \"version\" : n, (numeric) The version\n"
153 " \"locktime\" : ttt, (numeric) The lock time\n"
154 " \"vin\" : [ (array of json objects)\n"
155 " {\n"
156 " \"txid\": \"id\", (string) The transaction id\n"
157 " \"vout\": n, (numeric) \n"
158 " \"scriptSig\": { (json object) The script\n"
159 " \"asm\": \"asm\", (string) asm\n"
160 " \"hex\": \"hex\" (string) hex\n"
161 " },\n"
162 " \"sequence\": n (numeric) The script sequence number\n"
163 " \"txinwitness\": [\"hex\", ...] (array of string) hex-encoded witness data (if any)\n"
164 " }\n"
165 " ,...\n"
166 " ],\n"
167 " \"vout\" : [ (array of json objects)\n"
168 " {\n"
169 " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n"
170 " \"n\" : n, (numeric) index\n"
171 " \"scriptPubKey\" : { (json object)\n"
172 " \"asm\" : \"asm\", (string) the asm\n"
173 " \"hex\" : \"hex\", (string) the hex\n"
174 " \"reqSigs\" : n, (numeric) The required sigs\n"
175 " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
176 " \"addresses\" : [ (json array of string)\n"
177 " \"bitcoinaddress\" (string) bitcoin address\n"
178 " ,...\n"
179 " ]\n"
180 " }\n"
181 " }\n"
182 " ,...\n"
183 " ],\n"
184 " \"blockhash\" : \"hash\", (string) the block hash\n"
185 " \"confirmations\" : n, (numeric) The confirmations\n"
186 " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT)\n"
187 " \"blocktime\" : ttt (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
188 "}\n"
190 "\nExamples:\n"
191 + HelpExampleCli("getrawtransaction", "\"mytxid\"")
192 + HelpExampleCli("getrawtransaction", "\"mytxid\" true")
193 + HelpExampleRpc("getrawtransaction", "\"mytxid\", true")
196 LOCK(cs_main);
198 uint256 hash = ParseHashV(request.params[0], "parameter 1");
200 // Accept either a bool (true) or a num (>=1) to indicate verbose output.
201 bool fVerbose = false;
202 if (request.params.size() > 1) {
203 if (request.params[1].isNum()) {
204 if (request.params[1].get_int() != 0) {
205 fVerbose = true;
208 else if(request.params[1].isBool()) {
209 if(request.params[1].isTrue()) {
210 fVerbose = true;
213 else {
214 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid type provided. Verbose parameter must be a boolean.");
218 CTransactionRef tx;
219 uint256 hashBlock;
220 if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true))
221 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction");
223 string strHex = EncodeHexTx(*tx);
225 if (!fVerbose)
226 return strHex;
228 UniValue result(UniValue::VOBJ);
229 result.push_back(Pair("hex", strHex));
230 TxToJSON(*tx, hashBlock, result);
231 return result;
234 UniValue gettxoutproof(const JSONRPCRequest& request)
236 if (request.fHelp || (request.params.size() != 1 && request.params.size() != 2))
237 throw runtime_error(
238 "gettxoutproof [\"txid\",...] ( blockhash )\n"
239 "\nReturns a hex-encoded proof that \"txid\" was included in a block.\n"
240 "\nNOTE: By default this function only works sometimes. This is when there is an\n"
241 "unspent output in the utxo for this transaction. To make it always work,\n"
242 "you need to maintain a transaction index, using the -txindex command line option or\n"
243 "specify the block in which the transaction is included manually (by blockhash).\n"
244 "\nReturn the raw transaction data.\n"
245 "\nArguments:\n"
246 "1. \"txids\" (string) A json array of txids to filter\n"
247 " [\n"
248 " \"txid\" (string) A transaction hash\n"
249 " ,...\n"
250 " ]\n"
251 "2. \"block hash\" (string, optional) If specified, looks for txid in the block with this hash\n"
252 "\nResult:\n"
253 "\"data\" (string) A string that is a serialized, hex-encoded data for the proof.\n"
256 set<uint256> setTxids;
257 uint256 oneTxid;
258 UniValue txids = request.params[0].get_array();
259 for (unsigned int idx = 0; idx < txids.size(); idx++) {
260 const UniValue& txid = txids[idx];
261 if (txid.get_str().length() != 64 || !IsHex(txid.get_str()))
262 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid txid ")+txid.get_str());
263 uint256 hash(uint256S(txid.get_str()));
264 if (setTxids.count(hash))
265 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated txid: ")+txid.get_str());
266 setTxids.insert(hash);
267 oneTxid = hash;
270 LOCK(cs_main);
272 CBlockIndex* pblockindex = NULL;
274 uint256 hashBlock;
275 if (request.params.size() > 1)
277 hashBlock = uint256S(request.params[1].get_str());
278 if (!mapBlockIndex.count(hashBlock))
279 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
280 pblockindex = mapBlockIndex[hashBlock];
281 } else {
282 CCoins coins;
283 if (pcoinsTip->GetCoins(oneTxid, coins) && coins.nHeight > 0 && coins.nHeight <= chainActive.Height())
284 pblockindex = chainActive[coins.nHeight];
287 if (pblockindex == NULL)
289 CTransactionRef tx;
290 if (!GetTransaction(oneTxid, tx, Params().GetConsensus(), hashBlock, false) || hashBlock.IsNull())
291 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block");
292 if (!mapBlockIndex.count(hashBlock))
293 throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt");
294 pblockindex = mapBlockIndex[hashBlock];
297 CBlock block;
298 if(!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
299 throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
301 unsigned int ntxFound = 0;
302 for (const auto& tx : block.vtx)
303 if (setTxids.count(tx->GetHash()))
304 ntxFound++;
305 if (ntxFound != setTxids.size())
306 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "(Not all) transactions not found in specified block");
308 CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS);
309 CMerkleBlock mb(block, setTxids);
310 ssMB << mb;
311 std::string strHex = HexStr(ssMB.begin(), ssMB.end());
312 return strHex;
315 UniValue verifytxoutproof(const JSONRPCRequest& request)
317 if (request.fHelp || request.params.size() != 1)
318 throw runtime_error(
319 "verifytxoutproof \"proof\"\n"
320 "\nVerifies that a proof points to a transaction in a block, returning the transaction it commits to\n"
321 "and throwing an RPC error if the block is not in our best chain\n"
322 "\nArguments:\n"
323 "1. \"proof\" (string, required) The hex-encoded proof generated by gettxoutproof\n"
324 "\nResult:\n"
325 "[\"txid\"] (array, strings) The txid(s) which the proof commits to, or empty array if the proof is invalid\n"
328 CDataStream ssMB(ParseHexV(request.params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS);
329 CMerkleBlock merkleBlock;
330 ssMB >> merkleBlock;
332 UniValue res(UniValue::VARR);
334 vector<uint256> vMatch;
335 vector<unsigned int> vIndex;
336 if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) != merkleBlock.header.hashMerkleRoot)
337 return res;
339 LOCK(cs_main);
341 if (!mapBlockIndex.count(merkleBlock.header.GetHash()) || !chainActive.Contains(mapBlockIndex[merkleBlock.header.GetHash()]))
342 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain");
344 BOOST_FOREACH(const uint256& hash, vMatch)
345 res.push_back(hash.GetHex());
346 return res;
349 UniValue createrawtransaction(const JSONRPCRequest& request)
351 if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
352 throw runtime_error(
353 "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,\"data\":\"hex\",...} ( locktime )\n"
354 "\nCreate a transaction spending the given inputs and creating new outputs.\n"
355 "Outputs can be addresses or data.\n"
356 "Returns hex-encoded raw transaction.\n"
357 "Note that the transaction's inputs are not signed, and\n"
358 "it is not stored in the wallet or transmitted to the network.\n"
360 "\nArguments:\n"
361 "1. \"transactions\" (string, required) A json array of json objects\n"
362 " [\n"
363 " {\n"
364 " \"txid\":\"id\", (string, required) The transaction id\n"
365 " \"vout\":n (numeric, required) The output number\n"
366 " \"sequence\":n (numeric, optional) The sequence number\n"
367 " }\n"
368 " ,...\n"
369 " ]\n"
370 "2. \"outputs\" (string, required) a json object with outputs\n"
371 " {\n"
372 " \"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"
373 " \"data\": \"hex\", (string, required) The key is \"data\", the value is hex encoded data\n"
374 " ...\n"
375 " }\n"
376 "3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n"
377 "\nResult:\n"
378 "\"transaction\" (string) hex string of the transaction\n"
380 "\nExamples\n"
381 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":0.01}\"")
382 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"data\\\":\\\"00010203\\\"}\"")
383 + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\"")
384 + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"data\\\":\\\"00010203\\\"}\"")
387 RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VARR)(UniValue::VOBJ)(UniValue::VNUM), true);
388 if (request.params[0].isNull() || request.params[1].isNull())
389 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, arguments 1 and 2 must be non-null");
391 UniValue inputs = request.params[0].get_array();
392 UniValue sendTo = request.params[1].get_obj();
394 CMutableTransaction rawTx;
396 if (request.params.size() > 2 && !request.params[2].isNull()) {
397 int64_t nLockTime = request.params[2].get_int64();
398 if (nLockTime < 0 || nLockTime > std::numeric_limits<uint32_t>::max())
399 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, locktime out of range");
400 rawTx.nLockTime = nLockTime;
403 for (unsigned int idx = 0; idx < inputs.size(); idx++) {
404 const UniValue& input = inputs[idx];
405 const UniValue& o = input.get_obj();
407 uint256 txid = ParseHashO(o, "txid");
409 const UniValue& vout_v = find_value(o, "vout");
410 if (!vout_v.isNum())
411 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");
412 int nOutput = vout_v.get_int();
413 if (nOutput < 0)
414 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
416 uint32_t nSequence = (rawTx.nLockTime ? std::numeric_limits<uint32_t>::max() - 1 : std::numeric_limits<uint32_t>::max());
418 // set the sequence number if passed in the parameters object
419 const UniValue& sequenceObj = find_value(o, "sequence");
420 if (sequenceObj.isNum()) {
421 int64_t seqNr64 = sequenceObj.get_int64();
422 if (seqNr64 < 0 || seqNr64 > std::numeric_limits<uint32_t>::max())
423 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, sequence number is out of range");
424 else
425 nSequence = (uint32_t)seqNr64;
428 CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence);
430 rawTx.vin.push_back(in);
433 set<CBitcoinAddress> setAddress;
434 vector<string> addrList = sendTo.getKeys();
435 BOOST_FOREACH(const string& name_, addrList) {
437 if (name_ == "data") {
438 std::vector<unsigned char> data = ParseHexV(sendTo[name_].getValStr(),"Data");
440 CTxOut out(0, CScript() << OP_RETURN << data);
441 rawTx.vout.push_back(out);
442 } else {
443 CBitcoinAddress address(name_);
444 if (!address.IsValid())
445 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+name_);
447 if (setAddress.count(address))
448 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+name_);
449 setAddress.insert(address);
451 CScript scriptPubKey = GetScriptForDestination(address.Get());
452 CAmount nAmount = AmountFromValue(sendTo[name_]);
454 CTxOut out(nAmount, scriptPubKey);
455 rawTx.vout.push_back(out);
459 return EncodeHexTx(rawTx);
462 UniValue decoderawtransaction(const JSONRPCRequest& request)
464 if (request.fHelp || request.params.size() != 1)
465 throw runtime_error(
466 "decoderawtransaction \"hexstring\"\n"
467 "\nReturn a JSON object representing the serialized, hex-encoded transaction.\n"
469 "\nArguments:\n"
470 "1. \"hex\" (string, required) The transaction hex string\n"
472 "\nResult:\n"
473 "{\n"
474 " \"txid\" : \"id\", (string) The transaction id\n"
475 " \"hash\" : \"id\", (string) The transaction hash (differs from txid for witness transactions)\n"
476 " \"size\" : n, (numeric) The transaction size\n"
477 " \"vsize\" : n, (numeric) The virtual transaction size (differs from size for witness transactions)\n"
478 " \"version\" : n, (numeric) The version\n"
479 " \"locktime\" : ttt, (numeric) The lock time\n"
480 " \"vin\" : [ (array of json objects)\n"
481 " {\n"
482 " \"txid\": \"id\", (string) The transaction id\n"
483 " \"vout\": n, (numeric) The output number\n"
484 " \"scriptSig\": { (json object) The script\n"
485 " \"asm\": \"asm\", (string) asm\n"
486 " \"hex\": \"hex\" (string) hex\n"
487 " },\n"
488 " \"txinwitness\": [\"hex\", ...] (array of string) hex-encoded witness data (if any)\n"
489 " \"sequence\": n (numeric) The script sequence number\n"
490 " }\n"
491 " ,...\n"
492 " ],\n"
493 " \"vout\" : [ (array of json objects)\n"
494 " {\n"
495 " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n"
496 " \"n\" : n, (numeric) index\n"
497 " \"scriptPubKey\" : { (json object)\n"
498 " \"asm\" : \"asm\", (string) the asm\n"
499 " \"hex\" : \"hex\", (string) the hex\n"
500 " \"reqSigs\" : n, (numeric) The required sigs\n"
501 " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
502 " \"addresses\" : [ (json array of string)\n"
503 " \"12tvKAXCxZjSmdNbao16dKXC8tRWfcF5oc\" (string) bitcoin address\n"
504 " ,...\n"
505 " ]\n"
506 " }\n"
507 " }\n"
508 " ,...\n"
509 " ],\n"
510 "}\n"
512 "\nExamples:\n"
513 + HelpExampleCli("decoderawtransaction", "\"hexstring\"")
514 + HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
517 LOCK(cs_main);
518 RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR));
520 CMutableTransaction mtx;
522 if (!DecodeHexTx(mtx, request.params[0].get_str(), true))
523 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
525 UniValue result(UniValue::VOBJ);
526 TxToJSON(CTransaction(std::move(mtx)), uint256(), result);
528 return result;
531 UniValue decodescript(const JSONRPCRequest& request)
533 if (request.fHelp || request.params.size() != 1)
534 throw runtime_error(
535 "decodescript \"hex\"\n"
536 "\nDecode a hex-encoded script.\n"
537 "\nArguments:\n"
538 "1. \"hex\" (string) the hex encoded script\n"
539 "\nResult:\n"
540 "{\n"
541 " \"asm\":\"asm\", (string) Script public key\n"
542 " \"hex\":\"hex\", (string) hex encoded public key\n"
543 " \"type\":\"type\", (string) The output type\n"
544 " \"reqSigs\": n, (numeric) The required signatures\n"
545 " \"addresses\": [ (json array of string)\n"
546 " \"address\" (string) bitcoin address\n"
547 " ,...\n"
548 " ],\n"
549 " \"p2sh\",\"address\" (string) address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH).\n"
550 "}\n"
551 "\nExamples:\n"
552 + HelpExampleCli("decodescript", "\"hexstring\"")
553 + HelpExampleRpc("decodescript", "\"hexstring\"")
556 RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR));
558 UniValue r(UniValue::VOBJ);
559 CScript script;
560 if (request.params[0].get_str().size() > 0){
561 vector<unsigned char> scriptData(ParseHexV(request.params[0], "argument"));
562 script = CScript(scriptData.begin(), scriptData.end());
563 } else {
564 // Empty scripts are valid
566 ScriptPubKeyToJSON(script, r, false);
568 UniValue type;
569 type = find_value(r, "type");
571 if (type.isStr() && type.get_str() != "scripthash") {
572 // P2SH cannot be wrapped in a P2SH. If this script is already a P2SH,
573 // don't return the address for a P2SH of the P2SH.
574 r.push_back(Pair("p2sh", CBitcoinAddress(CScriptID(script)).ToString()));
577 return r;
580 /** Pushes a JSON object for script verification or signing errors to vErrorsRet. */
581 static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std::string& strMessage)
583 UniValue entry(UniValue::VOBJ);
584 entry.push_back(Pair("txid", txin.prevout.hash.ToString()));
585 entry.push_back(Pair("vout", (uint64_t)txin.prevout.n));
586 entry.push_back(Pair("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
587 entry.push_back(Pair("sequence", (uint64_t)txin.nSequence));
588 entry.push_back(Pair("error", strMessage));
589 vErrorsRet.push_back(entry);
592 UniValue signrawtransaction(const JSONRPCRequest& request)
594 if (request.fHelp || request.params.size() < 1 || request.params.size() > 4)
595 throw runtime_error(
596 "signrawtransaction \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] [\"privatekey1\",...] sighashtype )\n"
597 "\nSign inputs for raw transaction (serialized, hex-encoded).\n"
598 "The second optional argument (may be null) is an array of previous transaction outputs that\n"
599 "this transaction depends on but may not yet be in the block chain.\n"
600 "The third optional argument (may be null) is an array of base58-encoded private\n"
601 "keys that, if given, will be the only keys used to sign the transaction.\n"
602 #ifdef ENABLE_WALLET
603 + HelpRequiringPassphrase() + "\n"
604 #endif
606 "\nArguments:\n"
607 "1. \"hexstring\" (string, required) The transaction hex string\n"
608 "2. \"prevtxs\" (string, optional) An json array of previous dependent transaction outputs\n"
609 " [ (json array of json objects, or 'null' if none provided)\n"
610 " {\n"
611 " \"txid\":\"id\", (string, required) The transaction id\n"
612 " \"vout\":n, (numeric, required) The output number\n"
613 " \"scriptPubKey\": \"hex\", (string, required) script key\n"
614 " \"redeemScript\": \"hex\", (string, required for P2SH or P2WSH) redeem script\n"
615 " \"amount\": value (numeric, required) The amount spent\n"
616 " }\n"
617 " ,...\n"
618 " ]\n"
619 "3. \"privatekeys\" (string, optional) A json array of base58-encoded private keys for signing\n"
620 " [ (json array of strings, or 'null' if none provided)\n"
621 " \"privatekey\" (string) private key in base58-encoding\n"
622 " ,...\n"
623 " ]\n"
624 "4. \"sighashtype\" (string, optional, default=ALL) The signature hash type. Must be one of\n"
625 " \"ALL\"\n"
626 " \"NONE\"\n"
627 " \"SINGLE\"\n"
628 " \"ALL|ANYONECANPAY\"\n"
629 " \"NONE|ANYONECANPAY\"\n"
630 " \"SINGLE|ANYONECANPAY\"\n"
632 "\nResult:\n"
633 "{\n"
634 " \"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n"
635 " \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n"
636 " \"errors\" : [ (json array of objects) Script verification errors (if there are any)\n"
637 " {\n"
638 " \"txid\" : \"hash\", (string) The hash of the referenced, previous transaction\n"
639 " \"vout\" : n, (numeric) The index of the output to spent and used as input\n"
640 " \"scriptSig\" : \"hex\", (string) The hex-encoded signature script\n"
641 " \"sequence\" : n, (numeric) Script sequence number\n"
642 " \"error\" : \"text\" (string) Verification or signing error related to the input\n"
643 " }\n"
644 " ,...\n"
645 " ]\n"
646 "}\n"
648 "\nExamples:\n"
649 + HelpExampleCli("signrawtransaction", "\"myhex\"")
650 + HelpExampleRpc("signrawtransaction", "\"myhex\"")
653 #ifdef ENABLE_WALLET
654 LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
655 #else
656 LOCK(cs_main);
657 #endif
658 RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR)(UniValue::VARR)(UniValue::VARR)(UniValue::VSTR), true);
660 vector<unsigned char> txData(ParseHexV(request.params[0], "argument 1"));
661 CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
662 vector<CMutableTransaction> txVariants;
663 while (!ssData.empty()) {
664 try {
665 CMutableTransaction tx;
666 ssData >> tx;
667 txVariants.push_back(tx);
669 catch (const std::exception&) {
670 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
674 if (txVariants.empty())
675 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transaction");
677 // mergedTx will end up with all the signatures; it
678 // starts as a clone of the rawtx:
679 CMutableTransaction mergedTx(txVariants[0]);
681 // Fetch previous transactions (inputs):
682 CCoinsView viewDummy;
683 CCoinsViewCache view(&viewDummy);
685 LOCK(mempool.cs);
686 CCoinsViewCache &viewChain = *pcoinsTip;
687 CCoinsViewMemPool viewMempool(&viewChain, mempool);
688 view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
690 BOOST_FOREACH(const CTxIn& txin, mergedTx.vin) {
691 const uint256& prevHash = txin.prevout.hash;
692 CCoins coins;
693 view.AccessCoins(prevHash); // this is certainly allowed to fail
696 view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
699 bool fGivenKeys = false;
700 CBasicKeyStore tempKeystore;
701 if (request.params.size() > 2 && !request.params[2].isNull()) {
702 fGivenKeys = true;
703 UniValue keys = request.params[2].get_array();
704 for (unsigned int idx = 0; idx < keys.size(); idx++) {
705 UniValue k = keys[idx];
706 CBitcoinSecret vchSecret;
707 bool fGood = vchSecret.SetString(k.get_str());
708 if (!fGood)
709 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
710 CKey key = vchSecret.GetKey();
711 if (!key.IsValid())
712 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
713 tempKeystore.AddKey(key);
716 #ifdef ENABLE_WALLET
717 else if (pwalletMain)
718 EnsureWalletIsUnlocked();
719 #endif
721 // Add previous txouts given in the RPC call:
722 if (request.params.size() > 1 && !request.params[1].isNull()) {
723 UniValue prevTxs = request.params[1].get_array();
724 for (unsigned int idx = 0; idx < prevTxs.size(); idx++) {
725 const UniValue& p = prevTxs[idx];
726 if (!p.isObject())
727 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}");
729 UniValue prevOut = p.get_obj();
731 RPCTypeCheckObj(prevOut,
733 {"txid", UniValueType(UniValue::VSTR)},
734 {"vout", UniValueType(UniValue::VNUM)},
735 {"scriptPubKey", UniValueType(UniValue::VSTR)},
738 uint256 txid = ParseHashO(prevOut, "txid");
740 int nOut = find_value(prevOut, "vout").get_int();
741 if (nOut < 0)
742 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout must be positive");
744 vector<unsigned char> pkData(ParseHexO(prevOut, "scriptPubKey"));
745 CScript scriptPubKey(pkData.begin(), pkData.end());
748 CCoinsModifier coins = view.ModifyCoins(txid);
749 if (coins->IsAvailable(nOut) && coins->vout[nOut].scriptPubKey != scriptPubKey) {
750 string err("Previous output scriptPubKey mismatch:\n");
751 err = err + ScriptToAsmStr(coins->vout[nOut].scriptPubKey) + "\nvs:\n"+
752 ScriptToAsmStr(scriptPubKey);
753 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err);
755 if ((unsigned int)nOut >= coins->vout.size())
756 coins->vout.resize(nOut+1);
757 coins->vout[nOut].scriptPubKey = scriptPubKey;
758 coins->vout[nOut].nValue = 0;
759 if (prevOut.exists("amount")) {
760 coins->vout[nOut].nValue = AmountFromValue(find_value(prevOut, "amount"));
764 // if redeemScript given and not using the local wallet (private keys
765 // given), add redeemScript to the tempKeystore so it can be signed:
766 if (fGivenKeys && (scriptPubKey.IsPayToScriptHash() || scriptPubKey.IsPayToWitnessScriptHash())) {
767 RPCTypeCheckObj(prevOut,
769 {"txid", UniValueType(UniValue::VSTR)},
770 {"vout", UniValueType(UniValue::VNUM)},
771 {"scriptPubKey", UniValueType(UniValue::VSTR)},
772 {"redeemScript", UniValueType(UniValue::VSTR)},
774 UniValue v = find_value(prevOut, "redeemScript");
775 if (!v.isNull()) {
776 vector<unsigned char> rsData(ParseHexV(v, "redeemScript"));
777 CScript redeemScript(rsData.begin(), rsData.end());
778 tempKeystore.AddCScript(redeemScript);
784 #ifdef ENABLE_WALLET
785 const CKeyStore& keystore = ((fGivenKeys || !pwalletMain) ? tempKeystore : *pwalletMain);
786 #else
787 const CKeyStore& keystore = tempKeystore;
788 #endif
790 int nHashType = SIGHASH_ALL;
791 if (request.params.size() > 3 && !request.params[3].isNull()) {
792 static map<string, int> mapSigHashValues =
793 boost::assign::map_list_of
794 (string("ALL"), int(SIGHASH_ALL))
795 (string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY))
796 (string("NONE"), int(SIGHASH_NONE))
797 (string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY))
798 (string("SINGLE"), int(SIGHASH_SINGLE))
799 (string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY))
801 string strHashType = request.params[3].get_str();
802 if (mapSigHashValues.count(strHashType))
803 nHashType = mapSigHashValues[strHashType];
804 else
805 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param");
808 bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
810 // Script verification errors
811 UniValue vErrors(UniValue::VARR);
813 // Use CTransaction for the constant parts of the
814 // transaction to avoid rehashing.
815 const CTransaction txConst(mergedTx);
816 // Sign what we can:
817 for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
818 CTxIn& txin = mergedTx.vin[i];
819 const CCoins* coins = view.AccessCoins(txin.prevout.hash);
820 if (coins == NULL || !coins->IsAvailable(txin.prevout.n)) {
821 TxInErrorToJSON(txin, vErrors, "Input not found or already spent");
822 continue;
824 const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey;
825 const CAmount& amount = coins->vout[txin.prevout.n].nValue;
827 SignatureData sigdata;
828 // Only sign SIGHASH_SINGLE if there's a corresponding output:
829 if (!fHashSingle || (i < mergedTx.vout.size()))
830 ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mergedTx, i, amount, nHashType), prevPubKey, sigdata);
832 // ... and merge in other signatures:
833 BOOST_FOREACH(const CMutableTransaction& txv, txVariants) {
834 sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(txv, i));
837 UpdateTransaction(mergedTx, i, sigdata);
839 ScriptError serror = SCRIPT_ERR_OK;
840 if (!VerifyScript(txin.scriptSig, prevPubKey, &txin.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount), &serror)) {
841 TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror));
844 bool fComplete = vErrors.empty();
846 UniValue result(UniValue::VOBJ);
847 result.push_back(Pair("hex", EncodeHexTx(mergedTx)));
848 result.push_back(Pair("complete", fComplete));
849 if (!vErrors.empty()) {
850 result.push_back(Pair("errors", vErrors));
853 return result;
856 UniValue sendrawtransaction(const JSONRPCRequest& request)
858 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
859 throw runtime_error(
860 "sendrawtransaction \"hexstring\" ( allowhighfees )\n"
861 "\nSubmits raw transaction (serialized, hex-encoded) to local node and network.\n"
862 "\nAlso see createrawtransaction and signrawtransaction calls.\n"
863 "\nArguments:\n"
864 "1. \"hexstring\" (string, required) The hex string of the raw transaction)\n"
865 "2. allowhighfees (boolean, optional, default=false) Allow high fees\n"
866 "\nResult:\n"
867 "\"hex\" (string) The transaction hash in hex\n"
868 "\nExamples:\n"
869 "\nCreate a transaction\n"
870 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") +
871 "Sign the transaction, and get back the hex\n"
872 + HelpExampleCli("signrawtransaction", "\"myhex\"") +
873 "\nSend the transaction (signed hex)\n"
874 + HelpExampleCli("sendrawtransaction", "\"signedhex\"") +
875 "\nAs a json rpc call\n"
876 + HelpExampleRpc("sendrawtransaction", "\"signedhex\"")
879 LOCK(cs_main);
880 RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR)(UniValue::VBOOL));
882 // parse hex string from parameter
883 CMutableTransaction mtx;
884 if (!DecodeHexTx(mtx, request.params[0].get_str()))
885 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
886 CTransaction tx(std::move(mtx));
887 uint256 hashTx = tx.GetHash();
889 bool fLimitFree = false;
890 CAmount nMaxRawTxFee = maxTxFee;
891 if (request.params.size() > 1 && request.params[1].get_bool())
892 nMaxRawTxFee = 0;
894 CCoinsViewCache &view = *pcoinsTip;
895 const CCoins* existingCoins = view.AccessCoins(hashTx);
896 bool fHaveMempool = mempool.exists(hashTx);
897 bool fHaveChain = existingCoins && existingCoins->nHeight < 1000000000;
898 if (!fHaveMempool && !fHaveChain) {
899 // push to local node and sync with wallets
900 CValidationState state;
901 bool fMissingInputs;
902 if (!AcceptToMemoryPool(mempool, state, tx, fLimitFree, &fMissingInputs, false, nMaxRawTxFee)) {
903 if (state.IsInvalid()) {
904 throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
905 } else {
906 if (fMissingInputs) {
907 throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs");
909 throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason());
912 } else if (fHaveChain) {
913 throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain");
915 if(!g_connman)
916 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
918 CInv inv(MSG_TX, hashTx);
919 g_connman->ForEachNode([&inv](CNode* pnode)
921 pnode->PushInventory(inv);
923 return hashTx.GetHex();
926 static const CRPCCommand commands[] =
927 { // category name actor (function) okSafeMode
928 // --------------------- ------------------------ ----------------------- ----------
929 { "rawtransactions", "getrawtransaction", &getrawtransaction, true },
930 { "rawtransactions", "createrawtransaction", &createrawtransaction, true },
931 { "rawtransactions", "decoderawtransaction", &decoderawtransaction, true },
932 { "rawtransactions", "decodescript", &decodescript, true },
933 { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false },
934 { "rawtransactions", "signrawtransaction", &signrawtransaction, false }, /* uses wallet if enabled */
936 { "blockchain", "gettxoutproof", &gettxoutproof, true },
937 { "blockchain", "verifytxoutproof", &verifytxoutproof, true },
940 void RegisterRawTransactionRPCCommands(CRPCTable &t)
942 for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
943 t.appendCommand(commands[vcidx].name, &commands[vcidx]);