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.
9 #include "consensus/validation.h"
13 #include "validation.h"
14 #include "merkleblock.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"
25 #include "utilstrencodings.h"
27 #include "wallet/wallet.h"
32 #include <boost/assign/list_of.hpp>
38 void ScriptPubKeyToJSON(const CScript
& scriptPubKey
, UniValue
& out
, bool fIncludeHex
)
41 vector
<CTxDestination
> addresses
;
44 out
.push_back(Pair("asm", ScriptToAsmStr(scriptPubKey
)));
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
)));
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
);
76 in
.push_back(Pair("coinbase", HexStr(txin
.scriptSig
.begin(), txin
.scriptSig
.end())));
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
));
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
));
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()));
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)
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"
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"
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"
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"
162 " \"sequence\": n (numeric) The script sequence number\n"
163 " \"txinwitness\": [\"hex\", ...] (array of string) hex-encoded witness data (if any)\n"
167 " \"vout\" : [ (array of json objects)\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"
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"
191 + HelpExampleCli("getrawtransaction", "\"mytxid\"")
192 + HelpExampleCli("getrawtransaction", "\"mytxid\" true")
193 + HelpExampleRpc("getrawtransaction", "\"mytxid\", true")
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) {
208 else if(request
.params
[1].isBool()) {
209 if(request
.params
[1].isTrue()) {
214 throw JSONRPCError(RPC_TYPE_ERROR
, "Invalid type provided. Verbose parameter must be a boolean.");
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
);
228 UniValue
result(UniValue::VOBJ
);
229 result
.push_back(Pair("hex", strHex
));
230 TxToJSON(*tx
, hashBlock
, result
);
234 UniValue
gettxoutproof(const JSONRPCRequest
& request
)
236 if (request
.fHelp
|| (request
.params
.size() != 1 && request
.params
.size() != 2))
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"
246 "1. \"txids\" (string) A json array of txids to filter\n"
248 " \"txid\" (string) A transaction hash\n"
251 "2. \"block hash\" (string, optional) If specified, looks for txid in the block with this hash\n"
253 "\"data\" (string) A string that is a serialized, hex-encoded data for the proof.\n"
256 set
<uint256
> setTxids
;
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
);
272 CBlockIndex
* pblockindex
= NULL
;
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
];
283 if (pcoinsTip
->GetCoins(oneTxid
, coins
) && coins
.nHeight
> 0 && coins
.nHeight
<= chainActive
.Height())
284 pblockindex
= chainActive
[coins
.nHeight
];
287 if (pblockindex
== NULL
)
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
];
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()))
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
);
311 std::string strHex
= HexStr(ssMB
.begin(), ssMB
.end());
315 UniValue
verifytxoutproof(const JSONRPCRequest
& request
)
317 if (request
.fHelp
|| request
.params
.size() != 1)
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"
323 "1. \"proof\" (string, required) The hex-encoded proof generated by gettxoutproof\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
;
332 UniValue
res(UniValue::VARR
);
334 vector
<uint256
> vMatch
;
335 vector
<unsigned int> vIndex
;
336 if (merkleBlock
.txn
.ExtractMatches(vMatch
, vIndex
) != merkleBlock
.header
.hashMerkleRoot
)
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());
349 UniValue
createrawtransaction(const JSONRPCRequest
& request
)
351 if (request
.fHelp
|| request
.params
.size() < 2 || request
.params
.size() > 3)
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"
361 "1. \"transactions\" (string, required) A json array of json objects\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"
370 "2. \"outputs\" (string, required) a json object with outputs\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"
376 "3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n"
378 "\"transaction\" (string) hex string of the transaction\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");
411 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Invalid parameter, missing vout key");
412 int nOutput
= vout_v
.get_int();
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");
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
);
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)
466 "decoderawtransaction \"hexstring\"\n"
467 "\nReturn a JSON object representing the serialized, hex-encoded transaction.\n"
470 "1. \"hex\" (string, required) The transaction hex string\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"
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"
488 " \"txinwitness\": [\"hex\", ...] (array of string) hex-encoded witness data (if any)\n"
489 " \"sequence\": n (numeric) The script sequence number\n"
493 " \"vout\" : [ (array of json objects)\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"
513 + HelpExampleCli("decoderawtransaction", "\"hexstring\"")
514 + HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
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
);
531 UniValue
decodescript(const JSONRPCRequest
& request
)
533 if (request
.fHelp
|| request
.params
.size() != 1)
535 "decodescript \"hex\"\n"
536 "\nDecode a hex-encoded script.\n"
538 "1. \"hex\" (string) the hex encoded script\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"
549 " \"p2sh\",\"address\" (string) address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH).\n"
552 + HelpExampleCli("decodescript", "\"hexstring\"")
553 + HelpExampleRpc("decodescript", "\"hexstring\"")
556 RPCTypeCheck(request
.params
, boost::assign::list_of(UniValue::VSTR
));
558 UniValue
r(UniValue::VOBJ
);
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());
564 // Empty scripts are valid
566 ScriptPubKeyToJSON(script
, r
, false);
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()));
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)
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"
603 + HelpRequiringPassphrase() + "\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"
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"
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"
624 "4. \"sighashtype\" (string, optional, default=ALL) The signature hash type. Must be one of\n"
628 " \"ALL|ANYONECANPAY\"\n"
629 " \"NONE|ANYONECANPAY\"\n"
630 " \"SINGLE|ANYONECANPAY\"\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"
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"
649 + HelpExampleCli("signrawtransaction", "\"myhex\"")
650 + HelpExampleRpc("signrawtransaction", "\"myhex\"")
654 LOCK2(cs_main
, pwalletMain
? &pwalletMain
->cs_wallet
: NULL
);
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()) {
665 CMutableTransaction 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
);
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
;
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()) {
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());
709 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Invalid private key");
710 CKey key
= vchSecret
.GetKey();
712 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Private key outside allowed range");
713 tempKeystore
.AddKey(key
);
717 else if (pwalletMain
)
718 EnsureWalletIsUnlocked();
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
];
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();
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");
776 vector
<unsigned char> rsData(ParseHexV(v
, "redeemScript"));
777 CScript
redeemScript(rsData
.begin(), rsData
.end());
778 tempKeystore
.AddCScript(redeemScript
);
785 const CKeyStore
& keystore
= ((fGivenKeys
|| !pwalletMain
) ? tempKeystore
: *pwalletMain
);
787 const CKeyStore
& keystore
= tempKeystore
;
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
];
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
);
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");
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
));
856 UniValue
sendrawtransaction(const JSONRPCRequest
& request
)
858 if (request
.fHelp
|| request
.params
.size() < 1 || request
.params
.size() > 2)
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"
864 "1. \"hexstring\" (string, required) The hex string of the raw transaction)\n"
865 "2. allowhighfees (boolean, optional, default=false) Allow high fees\n"
867 "\"hex\" (string) The transaction hash in hex\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\"")
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())
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
;
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()));
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");
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
]);