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 "consensus/upgrades.h"
7 #include "consensus/validation.h"
10 #include "deprecation.h"
14 #include "merkleblock.h"
16 #include "primitives/transaction.h"
17 #include "rpc/server.h"
18 #include "script/script.h"
19 #include "script/script_error.h"
20 #include "script/sign.h"
21 #include "script/standard.h"
24 #include "wallet/wallet.h"
29 #include <boost/assign/list_of.hpp>
35 void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex)
38 vector<CTxDestination> addresses;
41 out.push_back(Pair("asm", ScriptToAsmStr(scriptPubKey)));
43 out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
45 if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) {
46 out.push_back(Pair("type", GetTxnOutputType(type)));
50 out.push_back(Pair("reqSigs", nRequired));
51 out.push_back(Pair("type", GetTxnOutputType(type)));
53 UniValue a(UniValue::VARR);
54 for (const CTxDestination& addr : addresses) {
55 a.push_back(EncodeDestination(addr));
57 out.push_back(Pair("addresses", a));
61 UniValue TxJoinSplitToJSON(const CTransaction& tx) {
62 bool useGroth = tx.fOverwintered && tx.nVersion >= SAPLING_TX_VERSION;
63 UniValue vjoinsplit(UniValue::VARR);
64 for (unsigned int i = 0; i < tx.vjoinsplit.size(); i++) {
65 const JSDescription& jsdescription = tx.vjoinsplit[i];
66 UniValue joinsplit(UniValue::VOBJ);
68 joinsplit.push_back(Pair("vpub_old", ValueFromAmount(jsdescription.vpub_old)));
69 joinsplit.push_back(Pair("vpub_new", ValueFromAmount(jsdescription.vpub_new)));
71 joinsplit.push_back(Pair("anchor", jsdescription.anchor.GetHex()));
74 UniValue nullifiers(UniValue::VARR);
75 BOOST_FOREACH(const uint256 nf, jsdescription.nullifiers) {
76 nullifiers.push_back(nf.GetHex());
78 joinsplit.push_back(Pair("nullifiers", nullifiers));
82 UniValue commitments(UniValue::VARR);
83 BOOST_FOREACH(const uint256 commitment, jsdescription.commitments) {
84 commitments.push_back(commitment.GetHex());
86 joinsplit.push_back(Pair("commitments", commitments));
89 joinsplit.push_back(Pair("onetimePubKey", jsdescription.ephemeralKey.GetHex()));
90 joinsplit.push_back(Pair("randomSeed", jsdescription.randomSeed.GetHex()));
93 UniValue macs(UniValue::VARR);
94 BOOST_FOREACH(const uint256 mac, jsdescription.macs) {
95 macs.push_back(mac.GetHex());
97 joinsplit.push_back(Pair("macs", macs));
100 CDataStream ssProof(SER_NETWORK, PROTOCOL_VERSION);
101 auto ps = SproutProofSerializer<CDataStream>(ssProof, useGroth);
102 boost::apply_visitor(ps, jsdescription.proof);
103 joinsplit.push_back(Pair("proof", HexStr(ssProof.begin(), ssProof.end())));
106 UniValue ciphertexts(UniValue::VARR);
107 for (const ZCNoteEncryption::Ciphertext ct : jsdescription.ciphertexts) {
108 ciphertexts.push_back(HexStr(ct.begin(), ct.end()));
110 joinsplit.push_back(Pair("ciphertexts", ciphertexts));
113 vjoinsplit.push_back(joinsplit);
118 void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
120 entry.push_back(Pair("txid", tx.GetHash().GetHex()));
121 entry.push_back(Pair("overwintered", tx.fOverwintered));
122 entry.push_back(Pair("version", tx.nVersion));
123 if (tx.fOverwintered) {
124 entry.push_back(Pair("versiongroupid", HexInt(tx.nVersionGroupId)));
126 entry.push_back(Pair("locktime", (int64_t)tx.nLockTime));
127 if (tx.fOverwintered) {
128 entry.push_back(Pair("expiryheight", (int64_t)tx.nExpiryHeight));
130 UniValue vin(UniValue::VARR);
131 BOOST_FOREACH(const CTxIn& txin, tx.vin) {
132 UniValue in(UniValue::VOBJ);
134 in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
136 in.push_back(Pair("txid", txin.prevout.hash.GetHex()));
137 in.push_back(Pair("vout", (int64_t)txin.prevout.n));
138 UniValue o(UniValue::VOBJ);
139 o.push_back(Pair("asm", ScriptToAsmStr(txin.scriptSig, true)));
140 o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
141 in.push_back(Pair("scriptSig", o));
143 in.push_back(Pair("sequence", (int64_t)txin.nSequence));
146 entry.push_back(Pair("vin", vin));
147 UniValue vout(UniValue::VARR);
148 for (unsigned int i = 0; i < tx.vout.size(); i++) {
149 const CTxOut& txout = tx.vout[i];
150 UniValue out(UniValue::VOBJ);
151 out.push_back(Pair("value", ValueFromAmount(txout.nValue)));
152 out.push_back(Pair("valueZat", txout.nValue));
153 out.push_back(Pair("n", (int64_t)i));
154 UniValue o(UniValue::VOBJ);
155 ScriptPubKeyToJSON(txout.scriptPubKey, o, true);
156 out.push_back(Pair("scriptPubKey", o));
159 entry.push_back(Pair("vout", vout));
161 UniValue vjoinsplit = TxJoinSplitToJSON(tx);
162 entry.push_back(Pair("vjoinsplit", vjoinsplit));
164 if (!hashBlock.IsNull()) {
165 entry.push_back(Pair("blockhash", hashBlock.GetHex()));
166 BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
167 if (mi != mapBlockIndex.end() && (*mi).second) {
168 CBlockIndex* pindex = (*mi).second;
169 if (chainActive.Contains(pindex)) {
170 entry.push_back(Pair("confirmations", 1 + chainActive.Height() - pindex->nHeight));
171 entry.push_back(Pair("time", pindex->GetBlockTime()));
172 entry.push_back(Pair("blocktime", pindex->GetBlockTime()));
175 entry.push_back(Pair("confirmations", 0));
180 UniValue getrawtransaction(const UniValue& params, bool fHelp)
182 if (fHelp || params.size() < 1 || params.size() > 2)
184 "getrawtransaction \"txid\" ( verbose )\n"
185 "\nNOTE: By default this function only works sometimes. This is when the tx is in the mempool\n"
186 "or there is an unspent output in the utxo for this transaction. To make it always work,\n"
187 "you need to maintain a transaction index, using the -txindex command line option.\n"
188 "\nReturn the raw transaction data.\n"
189 "\nIf verbose=0, returns a string that is serialized, hex-encoded data for 'txid'.\n"
190 "If verbose is non-zero, returns an Object with information about 'txid'.\n"
193 "1. \"txid\" (string, required) The transaction id\n"
194 "2. verbose (numeric, optional, default=0) If 0, return a string, other return a json object\n"
196 "\nResult (if verbose is not set or set to 0):\n"
197 "\"data\" (string) The serialized, hex-encoded data for 'txid'\n"
199 "\nResult (if verbose > 0):\n"
201 " \"hex\" : \"data\", (string) The serialized, hex-encoded data for 'txid'\n"
202 " \"txid\" : \"id\", (string) The transaction id (same as provided)\n"
203 " \"version\" : n, (numeric) The version\n"
204 " \"locktime\" : ttt, (numeric) The lock time\n"
205 " \"expiryheight\" : ttt, (numeric, optional) The block height after which the transaction expires\n"
206 " \"vin\" : [ (array of json objects)\n"
208 " \"txid\": \"id\", (string) The transaction id\n"
209 " \"vout\": n, (numeric) \n"
210 " \"scriptSig\": { (json object) The script\n"
211 " \"asm\": \"asm\", (string) asm\n"
212 " \"hex\": \"hex\" (string) hex\n"
214 " \"sequence\": n (numeric) The script sequence number\n"
218 " \"vout\" : [ (array of json objects)\n"
220 " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n"
221 " \"n\" : n, (numeric) index\n"
222 " \"scriptPubKey\" : { (json object)\n"
223 " \"asm\" : \"asm\", (string) the asm\n"
224 " \"hex\" : \"hex\", (string) the hex\n"
225 " \"reqSigs\" : n, (numeric) The required sigs\n"
226 " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
227 " \"addresses\" : [ (json array of string)\n"
228 " \"zcashaddress\" (string) Zcash address\n"
235 " \"vjoinsplit\" : [ (array of json objects, only for version >= 2)\n"
237 " \"vpub_old\" : x.xxx, (numeric) public input value in " + CURRENCY_UNIT + "\n"
238 " \"vpub_new\" : x.xxx, (numeric) public output value in " + CURRENCY_UNIT + "\n"
239 " \"anchor\" : \"hex\", (string) the anchor\n"
240 " \"nullifiers\" : [ (json array of string)\n"
241 " \"hex\" (string) input note nullifier\n"
244 " \"commitments\" : [ (json array of string)\n"
245 " \"hex\" (string) output note commitment\n"
248 " \"onetimePubKey\" : \"hex\", (string) the onetime public key used to encrypt the ciphertexts\n"
249 " \"randomSeed\" : \"hex\", (string) the random seed\n"
250 " \"macs\" : [ (json array of string)\n"
251 " \"hex\" (string) input note MAC\n"
254 " \"proof\" : \"hex\", (string) the zero-knowledge proof\n"
255 " \"ciphertexts\" : [ (json array of string)\n"
256 " \"hex\" (string) output note ciphertext\n"
262 " \"blockhash\" : \"hash\", (string) the block hash\n"
263 " \"confirmations\" : n, (numeric) The confirmations\n"
264 " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT)\n"
265 " \"blocktime\" : ttt (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
269 + HelpExampleCli("getrawtransaction", "\"mytxid\"")
270 + HelpExampleCli("getrawtransaction", "\"mytxid\" 1")
271 + HelpExampleRpc("getrawtransaction", "\"mytxid\", 1")
276 uint256 hash = ParseHashV(params[0], "parameter 1");
278 bool fVerbose = false;
279 if (params.size() > 1)
280 fVerbose = (params[1].get_int() != 0);
284 if (!GetTransaction(hash, tx, hashBlock, true))
285 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction");
287 string strHex = EncodeHexTx(tx);
292 UniValue result(UniValue::VOBJ);
293 result.push_back(Pair("hex", strHex));
294 TxToJSON(tx, hashBlock, result);
298 UniValue gettxoutproof(const UniValue& params, bool fHelp)
300 if (fHelp || (params.size() != 1 && params.size() != 2))
302 "gettxoutproof [\"txid\",...] ( blockhash )\n"
303 "\nReturns a hex-encoded proof that \"txid\" was included in a block.\n"
304 "\nNOTE: By default this function only works sometimes. This is when there is an\n"
305 "unspent output in the utxo for this transaction. To make it always work,\n"
306 "you need to maintain a transaction index, using the -txindex command line option or\n"
307 "specify the block in which the transaction is included in manually (by blockhash).\n"
308 "\nReturn the raw transaction data.\n"
310 "1. \"txids\" (string) A json array of txids to filter\n"
312 " \"txid\" (string) A transaction hash\n"
315 "2. \"block hash\" (string, optional) If specified, looks for txid in the block with this hash\n"
317 "\"data\" (string) A string that is a serialized, hex-encoded data for the proof.\n"
320 set<uint256> setTxids;
322 UniValue txids = params[0].get_array();
323 for (size_t idx = 0; idx < txids.size(); idx++) {
324 const UniValue& txid = txids[idx];
325 if (txid.get_str().length() != 64 || !IsHex(txid.get_str()))
326 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid txid ")+txid.get_str());
327 uint256 hash(uint256S(txid.get_str()));
328 if (setTxids.count(hash))
329 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated txid: ")+txid.get_str());
330 setTxids.insert(hash);
336 CBlockIndex* pblockindex = NULL;
339 if (params.size() > 1)
341 hashBlock = uint256S(params[1].get_str());
342 if (!mapBlockIndex.count(hashBlock))
343 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
344 pblockindex = mapBlockIndex[hashBlock];
347 if (pcoinsTip->GetCoins(oneTxid, coins) && coins.nHeight > 0 && coins.nHeight <= chainActive.Height())
348 pblockindex = chainActive[coins.nHeight];
351 if (pblockindex == NULL)
354 if (!GetTransaction(oneTxid, tx, hashBlock, false) || hashBlock.IsNull())
355 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block");
356 if (!mapBlockIndex.count(hashBlock))
357 throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt");
358 pblockindex = mapBlockIndex[hashBlock];
362 if(!ReadBlockFromDisk(block, pblockindex))
363 throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
365 unsigned int ntxFound = 0;
366 BOOST_FOREACH(const CTransaction&tx, block.vtx)
367 if (setTxids.count(tx.GetHash()))
369 if (ntxFound != setTxids.size())
370 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "(Not all) transactions not found in specified block");
372 CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION);
373 CMerkleBlock mb(block, setTxids);
375 std::string strHex = HexStr(ssMB.begin(), ssMB.end());
379 UniValue verifytxoutproof(const UniValue& params, bool fHelp)
381 if (fHelp || params.size() != 1)
383 "verifytxoutproof \"proof\"\n"
384 "\nVerifies that a proof points to a transaction in a block, returning the transaction it commits to\n"
385 "and throwing an RPC error if the block is not in our best chain\n"
387 "1. \"proof\" (string, required) The hex-encoded proof generated by gettxoutproof\n"
389 "[\"txid\"] (array, strings) The txid(s) which the proof commits to, or empty array if the proof is invalid\n"
392 CDataStream ssMB(ParseHexV(params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION);
393 CMerkleBlock merkleBlock;
396 UniValue res(UniValue::VARR);
398 vector<uint256> vMatch;
399 if (merkleBlock.txn.ExtractMatches(vMatch) != merkleBlock.header.hashMerkleRoot)
404 if (!mapBlockIndex.count(merkleBlock.header.GetHash()) || !chainActive.Contains(mapBlockIndex[merkleBlock.header.GetHash()]))
405 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain");
407 BOOST_FOREACH(const uint256& hash, vMatch)
408 res.push_back(hash.GetHex());
412 UniValue createrawtransaction(const UniValue& params, bool fHelp)
414 if (fHelp || params.size() < 2 || params.size() > 4)
416 "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,...} ( locktime ) ( expiryheight )\n"
417 "\nCreate a transaction spending the given inputs and sending to the given addresses.\n"
418 "Returns hex-encoded raw transaction.\n"
419 "Note that the transaction's inputs are not signed, and\n"
420 "it is not stored in the wallet or transmitted to the network.\n"
423 "1. \"transactions\" (string, required) A json array of json objects\n"
426 " \"txid\":\"id\", (string, required) The transaction id\n"
427 " \"vout\":n (numeric, required) The output number\n"
428 " \"sequence\":n (numeric, optional) The sequence number\n"
432 "2. \"addresses\" (string, required) a json object with addresses as keys and amounts as values\n"
434 " \"address\": x.xxx (numeric, required) The key is the Zcash address, the value is the " + CURRENCY_UNIT + " amount\n"
437 "3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n"
438 "4. expiryheight (numeric, optional, default=" + strprintf("%d", DEFAULT_TX_EXPIRY_DELTA) + ") Expiry height of transaction (if Overwinter is active)\n"
440 "\"transaction\" (string) hex string of the transaction\n"
443 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":0.01}\"")
444 + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\"")
448 RPCTypeCheck(params, boost::assign::list_of(UniValue::VARR)(UniValue::VOBJ)(UniValue::VNUM)(UniValue::VNUM), true);
449 if (params[0].isNull() || params[1].isNull())
450 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, arguments 1 and 2 must be non-null");
452 UniValue inputs = params[0].get_array();
453 UniValue sendTo = params[1].get_obj();
455 int nextBlockHeight = chainActive.Height() + 1;
456 CMutableTransaction rawTx = CreateNewContextualCMutableTransaction(
457 Params().GetConsensus(), nextBlockHeight);
459 if (params.size() > 2 && !params[2].isNull()) {
460 int64_t nLockTime = params[2].get_int64();
461 if (nLockTime < 0 || nLockTime > std::numeric_limits<uint32_t>::max())
462 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, locktime out of range");
463 rawTx.nLockTime = nLockTime;
466 if (params.size() > 3 && !params[3].isNull()) {
467 if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
468 int64_t nExpiryHeight = params[3].get_int64();
469 if (nExpiryHeight < 0 || nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD) {
470 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, expiryheight must be nonnegative and less than %d.", TX_EXPIRY_HEIGHT_THRESHOLD));
472 rawTx.nExpiryHeight = nExpiryHeight;
474 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expiryheight can only be used if Overwinter is active when the transaction is mined");
478 for (size_t idx = 0; idx < inputs.size(); idx++) {
479 const UniValue& input = inputs[idx];
480 const UniValue& o = input.get_obj();
482 uint256 txid = ParseHashO(o, "txid");
484 const UniValue& vout_v = find_value(o, "vout");
486 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");
487 int nOutput = vout_v.get_int();
489 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
491 uint32_t nSequence = (rawTx.nLockTime ? std::numeric_limits<uint32_t>::max() - 1 : std::numeric_limits<uint32_t>::max());
493 // set the sequence number if passed in the parameters object
494 const UniValue& sequenceObj = find_value(o, "sequence");
495 if (sequenceObj.isNum())
496 nSequence = sequenceObj.get_int();
498 CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence);
500 rawTx.vin.push_back(in);
503 std::set<CTxDestination> destinations;
504 vector<string> addrList = sendTo.getKeys();
505 for (const std::string& name_ : addrList) {
506 CTxDestination destination = DecodeDestination(name_);
507 if (!IsValidDestination(destination)) {
508 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Zcash address: ") + name_);
511 if (!destinations.insert(destination).second) {
512 throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + name_);
515 CScript scriptPubKey = GetScriptForDestination(destination);
516 CAmount nAmount = AmountFromValue(sendTo[name_]);
518 CTxOut out(nAmount, scriptPubKey);
519 rawTx.vout.push_back(out);
522 return EncodeHexTx(rawTx);
525 UniValue decoderawtransaction(const UniValue& params, bool fHelp)
527 if (fHelp || params.size() != 1)
529 "decoderawtransaction \"hexstring\"\n"
530 "\nReturn a JSON object representing the serialized, hex-encoded transaction.\n"
533 "1. \"hex\" (string, required) The transaction hex string\n"
537 " \"txid\" : \"id\", (string) The transaction id\n"
538 " \"overwintered\" : bool (boolean) The Overwintered flag\n"
539 " \"version\" : n, (numeric) The version\n"
540 " \"versiongroupid\": \"hex\" (string, optional) The version group id (Overwintered txs)\n"
541 " \"locktime\" : ttt, (numeric) The lock time\n"
542 " \"expiryheight\" : n, (numeric, optional) Last valid block height for mining transaction (Overwintered txs)\n"
543 " \"vin\" : [ (array of json objects)\n"
545 " \"txid\": \"id\", (string) The transaction id\n"
546 " \"vout\": n, (numeric) The output number\n"
547 " \"scriptSig\": { (json object) The script\n"
548 " \"asm\": \"asm\", (string) asm\n"
549 " \"hex\": \"hex\" (string) hex\n"
551 " \"sequence\": n (numeric) The script sequence number\n"
555 " \"vout\" : [ (array of json objects)\n"
557 " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n"
558 " \"n\" : n, (numeric) index\n"
559 " \"scriptPubKey\" : { (json object)\n"
560 " \"asm\" : \"asm\", (string) the asm\n"
561 " \"hex\" : \"hex\", (string) the hex\n"
562 " \"reqSigs\" : n, (numeric) The required sigs\n"
563 " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
564 " \"addresses\" : [ (json array of string)\n"
565 " \"t12tvKAXCxZjSmdNbao16dKXC8tRWfcF5oc\" (string) zcash address\n"
572 " \"vjoinsplit\" : [ (array of json objects, only for version >= 2)\n"
574 " \"vpub_old\" : x.xxx, (numeric) public input value in " + CURRENCY_UNIT + "\n"
575 " \"vpub_new\" : x.xxx, (numeric) public output value in " + CURRENCY_UNIT + "\n"
576 " \"anchor\" : \"hex\", (string) the anchor\n"
577 " \"nullifiers\" : [ (json array of string)\n"
578 " \"hex\" (string) input note nullifier\n"
581 " \"commitments\" : [ (json array of string)\n"
582 " \"hex\" (string) output note commitment\n"
585 " \"onetimePubKey\" : \"hex\", (string) the onetime public key used to encrypt the ciphertexts\n"
586 " \"randomSeed\" : \"hex\", (string) the random seed\n"
587 " \"macs\" : [ (json array of string)\n"
588 " \"hex\" (string) input note MAC\n"
591 " \"proof\" : \"hex\", (string) the zero-knowledge proof\n"
592 " \"ciphertexts\" : [ (json array of string)\n"
593 " \"hex\" (string) output note ciphertext\n"
602 + HelpExampleCli("decoderawtransaction", "\"hexstring\"")
603 + HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
607 RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR));
611 if (!DecodeHexTx(tx, params[0].get_str()))
612 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
614 UniValue result(UniValue::VOBJ);
615 TxToJSON(tx, uint256(), result);
620 UniValue decodescript(const UniValue& params, bool fHelp)
622 if (fHelp || params.size() != 1)
624 "decodescript \"hex\"\n"
625 "\nDecode a hex-encoded script.\n"
627 "1. \"hex\" (string) the hex encoded script\n"
630 " \"asm\":\"asm\", (string) Script public key\n"
631 " \"hex\":\"hex\", (string) hex encoded public key\n"
632 " \"type\":\"type\", (string) The output type\n"
633 " \"reqSigs\": n, (numeric) The required signatures\n"
634 " \"addresses\": [ (json array of string)\n"
635 " \"address\" (string) Zcash address\n"
638 " \"p2sh\",\"address\" (string) script address\n"
641 + HelpExampleCli("decodescript", "\"hexstring\"")
642 + HelpExampleRpc("decodescript", "\"hexstring\"")
646 RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR));
648 UniValue r(UniValue::VOBJ);
650 if (params[0].get_str().size() > 0){
651 vector<unsigned char> scriptData(ParseHexV(params[0], "argument"));
652 script = CScript(scriptData.begin(), scriptData.end());
654 // Empty scripts are valid
656 ScriptPubKeyToJSON(script, r, false);
658 r.push_back(Pair("p2sh", EncodeDestination(CScriptID(script))));
662 /** Pushes a JSON object for script verification or signing errors to vErrorsRet. */
663 static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std::string& strMessage)
665 UniValue entry(UniValue::VOBJ);
666 entry.push_back(Pair("txid", txin.prevout.hash.ToString()));
667 entry.push_back(Pair("vout", (uint64_t)txin.prevout.n));
668 entry.push_back(Pair("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
669 entry.push_back(Pair("sequence", (uint64_t)txin.nSequence));
670 entry.push_back(Pair("error", strMessage));
671 vErrorsRet.push_back(entry);
674 UniValue signrawtransaction(const UniValue& params, bool fHelp)
676 if (fHelp || params.size() < 1 || params.size() > 5)
678 "signrawtransaction \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] [\"privatekey1\",...] sighashtype )\n"
679 "\nSign inputs for raw transaction (serialized, hex-encoded).\n"
680 "The second optional argument (may be null) is an array of previous transaction outputs that\n"
681 "this transaction depends on but may not yet be in the block chain.\n"
682 "The third optional argument (may be null) is an array of base58-encoded private\n"
683 "keys that, if given, will be the only keys used to sign the transaction.\n"
685 + HelpRequiringPassphrase() + "\n"
689 "1. \"hexstring\" (string, required) The transaction hex string\n"
690 "2. \"prevtxs\" (string, optional) An json array of previous dependent transaction outputs\n"
691 " [ (json array of json objects, or 'null' if none provided)\n"
693 " \"txid\":\"id\", (string, required) The transaction id\n"
694 " \"vout\":n, (numeric, required) The output number\n"
695 " \"scriptPubKey\": \"hex\", (string, required) script key\n"
696 " \"redeemScript\": \"hex\", (string, required for P2SH) redeem script\n"
697 " \"amount\": value (numeric, required) The amount spent\n"
701 "3. \"privatekeys\" (string, optional) A json array of base58-encoded private keys for signing\n"
702 " [ (json array of strings, or 'null' if none provided)\n"
703 " \"privatekey\" (string) private key in base58-encoding\n"
706 "4. \"sighashtype\" (string, optional, default=ALL) The signature hash type. Must be one of\n"
710 " \"ALL|ANYONECANPAY\"\n"
711 " \"NONE|ANYONECANPAY\"\n"
712 " \"SINGLE|ANYONECANPAY\"\n"
713 "5. \"branchid\" (string, optional) The hex representation of the consensus branch id to sign with."
714 " This can be used to force signing with consensus rules that are ahead of the node's current height.\n"
718 " \"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n"
719 " \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n"
720 " \"errors\" : [ (json array of objects) Script verification errors (if there are any)\n"
722 " \"txid\" : \"hash\", (string) The hash of the referenced, previous transaction\n"
723 " \"vout\" : n, (numeric) The index of the output to spent and used as input\n"
724 " \"scriptSig\" : \"hex\", (string) The hex-encoded signature script\n"
725 " \"sequence\" : n, (numeric) Script sequence number\n"
726 " \"error\" : \"text\" (string) Verification or signing error related to the input\n"
733 + HelpExampleCli("signrawtransaction", "\"myhex\"")
734 + HelpExampleRpc("signrawtransaction", "\"myhex\"")
738 LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
742 RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VARR)(UniValue::VARR)(UniValue::VSTR)(UniValue::VSTR), true);
744 vector<unsigned char> txData(ParseHexV(params[0], "argument 1"));
745 CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
746 vector<CMutableTransaction> txVariants;
747 while (!ssData.empty()) {
749 CMutableTransaction tx;
751 txVariants.push_back(tx);
753 catch (const std::exception&) {
754 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
758 if (txVariants.empty())
759 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transaction");
761 // mergedTx will end up with all the signatures; it
762 // starts as a clone of the rawtx:
763 CMutableTransaction mergedTx(txVariants[0]);
765 // Fetch previous transactions (inputs):
766 CCoinsView viewDummy;
767 CCoinsViewCache view(&viewDummy);
770 CCoinsViewCache &viewChain = *pcoinsTip;
771 CCoinsViewMemPool viewMempool(&viewChain, mempool);
772 view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
774 BOOST_FOREACH(const CTxIn& txin, mergedTx.vin) {
775 const uint256& prevHash = txin.prevout.hash;
777 view.AccessCoins(prevHash); // this is certainly allowed to fail
780 view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
783 bool fGivenKeys = false;
784 CBasicKeyStore tempKeystore;
785 if (params.size() > 2 && !params[2].isNull()) {
787 UniValue keys = params[2].get_array();
788 for (size_t idx = 0; idx < keys.size(); idx++) {
789 UniValue k = keys[idx];
790 CKey key = DecodeSecret(k.get_str());
792 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
793 tempKeystore.AddKey(key);
797 else if (pwalletMain)
798 EnsureWalletIsUnlocked();
801 // Add previous txouts given in the RPC call:
802 if (params.size() > 1 && !params[1].isNull()) {
803 UniValue prevTxs = params[1].get_array();
804 for (size_t idx = 0; idx < prevTxs.size(); idx++) {
805 const UniValue& p = prevTxs[idx];
807 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}");
809 UniValue prevOut = p.get_obj();
811 RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR));
813 uint256 txid = ParseHashO(prevOut, "txid");
815 int nOut = find_value(prevOut, "vout").get_int();
817 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout must be positive");
819 vector<unsigned char> pkData(ParseHexO(prevOut, "scriptPubKey"));
820 CScript scriptPubKey(pkData.begin(), pkData.end());
823 CCoinsModifier coins = view.ModifyCoins(txid);
824 if (coins->IsAvailable(nOut) && coins->vout[nOut].scriptPubKey != scriptPubKey) {
825 string err("Previous output scriptPubKey mismatch:\n");
826 err = err + ScriptToAsmStr(coins->vout[nOut].scriptPubKey) + "\nvs:\n"+
827 ScriptToAsmStr(scriptPubKey);
828 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err);
830 if ((unsigned int)nOut >= coins->vout.size())
831 coins->vout.resize(nOut+1);
832 coins->vout[nOut].scriptPubKey = scriptPubKey;
833 coins->vout[nOut].nValue = 0;
834 if (prevOut.exists("amount")) {
835 coins->vout[nOut].nValue = AmountFromValue(find_value(prevOut, "amount"));
839 // if redeemScript given and not using the local wallet (private keys
840 // given), add redeemScript to the tempKeystore so it can be signed:
841 if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) {
842 RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR)("redeemScript",UniValue::VSTR));
843 UniValue v = find_value(prevOut, "redeemScript");
845 vector<unsigned char> rsData(ParseHexV(v, "redeemScript"));
846 CScript redeemScript(rsData.begin(), rsData.end());
847 tempKeystore.AddCScript(redeemScript);
854 const CKeyStore& keystore = ((fGivenKeys || !pwalletMain) ? tempKeystore : *pwalletMain);
856 const CKeyStore& keystore = tempKeystore;
859 int nHashType = SIGHASH_ALL;
860 if (params.size() > 3 && !params[3].isNull()) {
861 static map<string, int> mapSigHashValues =
862 boost::assign::map_list_of
863 (string("ALL"), int(SIGHASH_ALL))
864 (string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY))
865 (string("NONE"), int(SIGHASH_NONE))
866 (string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY))
867 (string("SINGLE"), int(SIGHASH_SINGLE))
868 (string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY))
870 string strHashType = params[3].get_str();
871 if (mapSigHashValues.count(strHashType))
872 nHashType = mapSigHashValues[strHashType];
874 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param");
877 bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
878 // Use the approximate release height if it is greater so offline nodes
879 // have a better estimation of the current height and will be more likely to
880 // determine the correct consensus branch ID.
881 int chainHeight = std::max(chainActive.Height() + 1, APPROX_RELEASE_HEIGHT);
882 // Grab the current consensus branch ID
883 auto consensusBranchId = CurrentEpochBranchId(chainHeight, Params().GetConsensus());
885 if (params.size() > 4 && !params[4].isNull()) {
886 consensusBranchId = ParseHexToUInt32(params[4].get_str());
887 if (!IsConsensusBranchId(consensusBranchId)) {
888 throw runtime_error(params[4].get_str() + " is not a valid consensus branch id");
892 // Script verification errors
893 UniValue vErrors(UniValue::VARR);
895 // Use CTransaction for the constant parts of the
896 // transaction to avoid rehashing.
897 const CTransaction txConst(mergedTx);
899 for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
900 CTxIn& txin = mergedTx.vin[i];
901 const CCoins* coins = view.AccessCoins(txin.prevout.hash);
902 if (coins == NULL || !coins->IsAvailable(txin.prevout.n)) {
903 TxInErrorToJSON(txin, vErrors, "Input not found or already spent");
906 const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey;
907 const CAmount& amount = coins->vout[txin.prevout.n].nValue;
909 SignatureData sigdata;
910 // Only sign SIGHASH_SINGLE if there's a corresponding output:
911 if (!fHashSingle || (i < mergedTx.vout.size()))
912 ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mergedTx, i, amount, nHashType), prevPubKey, sigdata, consensusBranchId);
914 // ... and merge in other signatures:
915 BOOST_FOREACH(const CMutableTransaction& txv, txVariants) {
916 sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(txv, i), consensusBranchId);
919 UpdateTransaction(mergedTx, i, sigdata);
921 ScriptError serror = SCRIPT_ERR_OK;
922 if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount), consensusBranchId, &serror)) {
923 TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror));
926 bool fComplete = vErrors.empty();
928 UniValue result(UniValue::VOBJ);
929 result.push_back(Pair("hex", EncodeHexTx(mergedTx)));
930 result.push_back(Pair("complete", fComplete));
931 if (!vErrors.empty()) {
932 result.push_back(Pair("errors", vErrors));
938 UniValue sendrawtransaction(const UniValue& params, bool fHelp)
940 if (fHelp || params.size() < 1 || params.size() > 2)
942 "sendrawtransaction \"hexstring\" ( allowhighfees )\n"
943 "\nSubmits raw transaction (serialized, hex-encoded) to local node and network.\n"
944 "\nAlso see createrawtransaction and signrawtransaction calls.\n"
946 "1. \"hexstring\" (string, required) The hex string of the raw transaction)\n"
947 "2. allowhighfees (boolean, optional, default=false) Allow high fees\n"
949 "\"hex\" (string) The transaction hash in hex\n"
951 "\nCreate a transaction\n"
952 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") +
953 "Sign the transaction, and get back the hex\n"
954 + HelpExampleCli("signrawtransaction", "\"myhex\"") +
955 "\nSend the transaction (signed hex)\n"
956 + HelpExampleCli("sendrawtransaction", "\"signedhex\"") +
957 "\nAs a json rpc call\n"
958 + HelpExampleRpc("sendrawtransaction", "\"signedhex\"")
962 RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VBOOL));
964 // parse hex string from parameter
966 if (!DecodeHexTx(tx, params[0].get_str()))
967 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
968 uint256 hashTx = tx.GetHash();
970 bool fOverrideFees = false;
971 if (params.size() > 1)
972 fOverrideFees = params[1].get_bool();
974 CCoinsViewCache &view = *pcoinsTip;
975 const CCoins* existingCoins = view.AccessCoins(hashTx);
976 bool fHaveMempool = mempool.exists(hashTx);
977 bool fHaveChain = existingCoins && existingCoins->nHeight < 1000000000;
978 if (!fHaveMempool && !fHaveChain) {
979 // push to local node and sync with wallets
980 CValidationState state;
982 if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees)) {
983 if (state.IsInvalid()) {
984 throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
986 if (fMissingInputs) {
987 throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs");
989 throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason());
992 } else if (fHaveChain) {
993 throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain");
995 RelayTransaction(tx);
997 return hashTx.GetHex();
1000 static const CRPCCommand commands[] =
1001 { // category name actor (function) okSafeMode
1002 // --------------------- ------------------------ ----------------------- ----------
1003 { "rawtransactions", "getrawtransaction", &getrawtransaction, true },
1004 { "rawtransactions", "createrawtransaction", &createrawtransaction, true },
1005 { "rawtransactions", "decoderawtransaction", &decoderawtransaction, true },
1006 { "rawtransactions", "decodescript", &decodescript, true },
1007 { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false },
1008 { "rawtransactions", "signrawtransaction", &signrawtransaction, false }, /* uses wallet if enabled */
1010 { "blockchain", "gettxoutproof", &gettxoutproof, true },
1011 { "blockchain", "verifytxoutproof", &verifytxoutproof, true },
1014 void RegisterRawTransactionRPCCommands(CRPCTable &tableRPC)
1016 for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
1017 tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);