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.
7 #include "consensus/validation.h"
12 #include "merkleblock.h"
14 #include "primitives/transaction.h"
15 #include "rpcserver.h"
16 #include "script/script.h"
17 #include "script/script_error.h"
18 #include "script/sign.h"
19 #include "script/standard.h"
22 #include "wallet/wallet.h"
27 #include <boost/assign/list_of.hpp>
28 #include "json/json_spirit_utils.h"
29 #include "json/json_spirit_value.h"
31 using namespace json_spirit;
34 void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex)
37 vector<CTxDestination> addresses;
40 out.push_back(Pair("asm", scriptPubKey.ToString()));
42 out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
44 if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) {
45 out.push_back(Pair("type", GetTxnOutputType(type)));
49 out.push_back(Pair("reqSigs", nRequired));
50 out.push_back(Pair("type", GetTxnOutputType(type)));
53 BOOST_FOREACH(const CTxDestination& addr, addresses)
54 a.push_back(CBitcoinAddress(addr).ToString());
55 out.push_back(Pair("addresses", a));
59 Array TxJoinSplitToJSON(const CTransaction& tx) {
61 for (unsigned int i = 0; i < tx.vjoinsplit.size(); i++) {
62 const JSDescription& jsdescription = tx.vjoinsplit[i];
65 joinsplit.push_back(Pair("anchor", jsdescription.anchor.GetHex()));
69 BOOST_FOREACH(const uint256 nf, jsdescription.nullifiers) {
70 nullifiers.push_back(nf.GetHex());
72 joinsplit.push_back(Pair("nullifiers", nullifiers));
77 BOOST_FOREACH(const uint256 commitment, jsdescription.commitments) {
78 commitments.push_back(commitment.GetHex());
80 joinsplit.push_back(Pair("commitments", commitments));
85 BOOST_FOREACH(const uint256 mac, jsdescription.macs) {
86 macs.push_back(mac.GetHex());
88 joinsplit.push_back(Pair("macs", macs));
91 joinsplit.push_back(Pair("vpub_old", ValueFromAmount(jsdescription.vpub_old)));
92 joinsplit.push_back(Pair("vpub_new", ValueFromAmount(jsdescription.vpub_new)));
94 vjoinsplit.push_back(joinsplit);
99 uint64_t komodo_interest(uint64_t nValue,uint32_t pastlocktime,uint32_t tiptime);
101 void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry)
103 entry.push_back(Pair("txid", tx.GetHash().GetHex()));
104 entry.push_back(Pair("version", tx.nVersion));
105 entry.push_back(Pair("locktime", (int64_t)tx.nLockTime));
107 BOOST_FOREACH(const CTxIn& txin, tx.vin) {
110 in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
112 in.push_back(Pair("txid", txin.prevout.hash.GetHex()));
113 in.push_back(Pair("vout", (int64_t)txin.prevout.n));
115 o.push_back(Pair("asm", txin.scriptSig.ToString()));
116 o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
117 in.push_back(Pair("scriptSig", o));
119 in.push_back(Pair("sequence", (int64_t)txin.nSequence));
122 entry.push_back(Pair("vin", vin));
125 for (unsigned int i = 0; i < tx.vout.size(); i++) {
126 const CTxOut& txout = tx.vout[i];
128 out.push_back(Pair("value", ValueFromAmount(txout.nValue)));
129 interest = komodo_interest(txout.nValue,tx.nLockTime,chainActive.Tip()->nTime));
130 fprintf(stderr,"TxtoJSON interest %llu %.8f\n",(long long)interest,(double)interest/COIN);
131 out.push_back(Pair("interest", ValueFromAmount(interest));
132 out.push_back(Pair("n", (int64_t)i));
134 ScriptPubKeyToJSON(txout.scriptPubKey, o, true);
135 out.push_back(Pair("scriptPubKey", o));
138 entry.push_back(Pair("vout", vout));
140 Array vjoinsplit = TxJoinSplitToJSON(tx);
141 entry.push_back(Pair("vjoinsplit", vjoinsplit));
143 if (!hashBlock.IsNull()) {
144 entry.push_back(Pair("blockhash", hashBlock.GetHex()));
145 BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
146 if (mi != mapBlockIndex.end() && (*mi).second) {
147 CBlockIndex* pindex = (*mi).second;
148 if (chainActive.Contains(pindex)) {
149 entry.push_back(Pair("confirmations", 1 + chainActive.Height() - pindex->nHeight));
150 entry.push_back(Pair("time", pindex->GetBlockTime()));
151 entry.push_back(Pair("blocktime", pindex->GetBlockTime()));
154 entry.push_back(Pair("confirmations", 0));
159 Value getrawtransaction(const Array& params, bool fHelp)
161 if (fHelp || params.size() < 1 || params.size() > 2)
163 "getrawtransaction \"txid\" ( verbose )\n"
164 "\nNOTE: By default this function only works sometimes. This is when the tx is in the mempool\n"
165 "or there is an unspent output in the utxo for this transaction. To make it always work,\n"
166 "you need to maintain a transaction index, using the -txindex command line option.\n"
167 "\nReturn the raw transaction data.\n"
168 "\nIf verbose=0, returns a string that is serialized, hex-encoded data for 'txid'.\n"
169 "If verbose is non-zero, returns an Object with information about 'txid'.\n"
172 "1. \"txid\" (string, required) The transaction id\n"
173 "2. verbose (numeric, optional, default=0) If 0, return a string, other return a json object\n"
175 "\nResult (if verbose is not set or set to 0):\n"
176 "\"data\" (string) The serialized, hex-encoded data for 'txid'\n"
178 "\nResult (if verbose > 0):\n"
180 " \"hex\" : \"data\", (string) The serialized, hex-encoded data for 'txid'\n"
181 " \"txid\" : \"id\", (string) The transaction id (same as provided)\n"
182 " \"version\" : n, (numeric) The version\n"
183 " \"locktime\" : ttt, (numeric) The lock time\n"
184 " \"vin\" : [ (array of json objects)\n"
186 " \"txid\": \"id\", (string) The transaction id\n"
187 " \"vout\": n, (numeric) \n"
188 " \"scriptSig\": { (json object) The script\n"
189 " \"asm\": \"asm\", (string) asm\n"
190 " \"hex\": \"hex\" (string) hex\n"
192 " \"sequence\": n (numeric) The script sequence number\n"
196 " \"vout\" : [ (array of json objects)\n"
198 " \"value\" : x.xxx, (numeric) The value in btc\n"
199 " \"n\" : n, (numeric) index\n"
200 " \"scriptPubKey\" : { (json object)\n"
201 " \"asm\" : \"asm\", (string) the asm\n"
202 " \"hex\" : \"hex\", (string) the hex\n"
203 " \"reqSigs\" : n, (numeric) The required sigs\n"
204 " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
205 " \"addresses\" : [ (json array of string)\n"
206 " \"bitcoinaddress\" (string) bitcoin address\n"
213 " \"blockhash\" : \"hash\", (string) the block hash\n"
214 " \"confirmations\" : n, (numeric) The confirmations\n"
215 " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT)\n"
216 " \"blocktime\" : ttt (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
220 + HelpExampleCli("getrawtransaction", "\"mytxid\"")
221 + HelpExampleCli("getrawtransaction", "\"mytxid\" 1")
222 + HelpExampleRpc("getrawtransaction", "\"mytxid\", 1")
227 uint256 hash = ParseHashV(params[0], "parameter 1");
229 bool fVerbose = false;
230 if (params.size() > 1)
231 fVerbose = (params[1].get_int() != 0);
235 if (!GetTransaction(hash, tx, hashBlock, true))
236 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction");
238 string strHex = EncodeHexTx(tx);
244 result.push_back(Pair("hex", strHex));
245 TxToJSON(tx, hashBlock, result);
249 Value gettxoutproof(const Array& params, bool fHelp)
251 if (fHelp || (params.size() != 1 && params.size() != 2))
253 "gettxoutproof [\"txid\",...] ( blockhash )\n"
254 "\nReturns a hex-encoded proof that \"txid\" was included in a block.\n"
255 "\nNOTE: By default this function only works sometimes. This is when there is an\n"
256 "unspent output in the utxo for this transaction. To make it always work,\n"
257 "you need to maintain a transaction index, using the -txindex command line option or\n"
258 "specify the block in which the transaction is included in manually (by blockhash).\n"
259 "\nReturn the raw transaction data.\n"
261 "1. \"txids\" (string) A json array of txids to filter\n"
263 " \"txid\" (string) A transaction hash\n"
266 "2. \"block hash\" (string, optional) If specified, looks for txid in the block with this hash\n"
268 "\"data\" (string) A string that is a serialized, hex-encoded data for the proof.\n"
271 set<uint256> setTxids;
273 Array txids = params[0].get_array();
274 BOOST_FOREACH(Value& txid, txids) {
275 if (txid.get_str().length() != 64 || !IsHex(txid.get_str()))
276 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid txid ")+txid.get_str());
277 uint256 hash(uint256S(txid.get_str()));
278 if (setTxids.count(hash))
279 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated txid: ")+txid.get_str());
280 setTxids.insert(hash);
286 CBlockIndex* pblockindex = NULL;
289 if (params.size() > 1)
291 hashBlock = uint256S(params[1].get_str());
292 if (!mapBlockIndex.count(hashBlock))
293 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
294 pblockindex = mapBlockIndex[hashBlock];
297 if (pcoinsTip->GetCoins(oneTxid, coins) && coins.nHeight > 0 && coins.nHeight <= chainActive.Height())
298 pblockindex = chainActive[coins.nHeight];
301 if (pblockindex == NULL)
304 if (!GetTransaction(oneTxid, tx, hashBlock, false) || hashBlock.IsNull())
305 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block");
306 if (!mapBlockIndex.count(hashBlock))
307 throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt");
308 pblockindex = mapBlockIndex[hashBlock];
312 if(!ReadBlockFromDisk(block, pblockindex))
313 throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
315 unsigned int ntxFound = 0;
316 BOOST_FOREACH(const CTransaction&tx, block.vtx)
317 if (setTxids.count(tx.GetHash()))
319 if (ntxFound != setTxids.size())
320 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "(Not all) transactions not found in specified block");
322 CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION);
323 CMerkleBlock mb(block, setTxids);
325 std::string strHex = HexStr(ssMB.begin(), ssMB.end());
329 Value verifytxoutproof(const Array& params, bool fHelp)
331 if (fHelp || params.size() != 1)
333 "verifytxoutproof \"proof\"\n"
334 "\nVerifies that a proof points to a transaction in a block, returning the transaction it commits to\n"
335 "and throwing an RPC error if the block is not in our best chain\n"
337 "1. \"proof\" (string, required) The hex-encoded proof generated by gettxoutproof\n"
339 "[\"txid\"] (array, strings) The txid(s) which the proof commits to, or empty array if the proof is invalid\n"
342 CDataStream ssMB(ParseHexV(params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION);
343 CMerkleBlock merkleBlock;
348 vector<uint256> vMatch;
349 if (merkleBlock.txn.ExtractMatches(vMatch) != merkleBlock.header.hashMerkleRoot)
354 if (!mapBlockIndex.count(merkleBlock.header.GetHash()) || !chainActive.Contains(mapBlockIndex[merkleBlock.header.GetHash()]))
355 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain");
357 BOOST_FOREACH(const uint256& hash, vMatch)
358 res.push_back(hash.GetHex());
362 Value createrawtransaction(const Array& params, bool fHelp)
364 if (fHelp || params.size() != 2)
366 "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,...}\n"
367 "\nCreate a transaction spending the given inputs and sending to the given addresses.\n"
368 "Returns hex-encoded raw transaction.\n"
369 "Note that the transaction's inputs are not signed, and\n"
370 "it is not stored in the wallet or transmitted to the network.\n"
373 "1. \"transactions\" (string, required) A json array of json objects\n"
376 " \"txid\":\"id\", (string, required) The transaction id\n"
377 " \"vout\":n (numeric, required) The output number\n"
381 "2. \"addresses\" (string, required) a json object with addresses as keys and amounts as values\n"
383 " \"address\": x.xxx (numeric, required) The key is the bitcoin address, the value is the btc amount\n"
388 "\"transaction\" (string) hex string of the transaction\n"
391 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":0.01}\"")
392 + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\"")
396 RPCTypeCheck(params, boost::assign::list_of(array_type)(obj_type));
398 Array inputs = params[0].get_array();
399 Object sendTo = params[1].get_obj();
401 CMutableTransaction rawTx;
403 BOOST_FOREACH(const Value& input, inputs) {
404 const Object& o = input.get_obj();
406 uint256 txid = ParseHashO(o, "txid");
408 const Value& vout_v = find_value(o, "vout");
409 if (vout_v.type() != int_type)
410 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");
411 int nOutput = vout_v.get_int();
413 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
415 CTxIn in(COutPoint(txid, nOutput));
416 rawTx.vin.push_back(in);
419 set<CBitcoinAddress> setAddress;
420 BOOST_FOREACH(const Pair& s, sendTo) {
421 CBitcoinAddress address(s.name_);
422 if (!address.IsValid())
423 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+s.name_);
425 if (setAddress.count(address))
426 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_);
427 setAddress.insert(address);
429 CScript scriptPubKey = GetScriptForDestination(address.Get());
430 CAmount nAmount = AmountFromValue(s.value_);
432 CTxOut out(nAmount, scriptPubKey);
433 rawTx.vout.push_back(out);
436 return EncodeHexTx(rawTx);
439 Value decoderawtransaction(const Array& params, bool fHelp)
441 if (fHelp || params.size() != 1)
443 "decoderawtransaction \"hexstring\"\n"
444 "\nReturn a JSON object representing the serialized, hex-encoded transaction.\n"
447 "1. \"hex\" (string, required) The transaction hex string\n"
451 " \"txid\" : \"id\", (string) The transaction id\n"
452 " \"version\" : n, (numeric) The version\n"
453 " \"locktime\" : ttt, (numeric) The lock time\n"
454 " \"vin\" : [ (array of json objects)\n"
456 " \"txid\": \"id\", (string) The transaction id\n"
457 " \"vout\": n, (numeric) The output number\n"
458 " \"scriptSig\": { (json object) The script\n"
459 " \"asm\": \"asm\", (string) asm\n"
460 " \"hex\": \"hex\" (string) hex\n"
462 " \"sequence\": n (numeric) The script sequence number\n"
466 " \"vout\" : [ (array of json objects)\n"
468 " \"value\" : x.xxx, (numeric) The value in btc\n"
469 " \"n\" : n, (numeric) index\n"
470 " \"scriptPubKey\" : { (json object)\n"
471 " \"asm\" : \"asm\", (string) the asm\n"
472 " \"hex\" : \"hex\", (string) the hex\n"
473 " \"reqSigs\" : n, (numeric) The required sigs\n"
474 " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
475 " \"addresses\" : [ (json array of string)\n"
476 " \"12tvKAXCxZjSmdNbao16dKXC8tRWfcF5oc\" (string) bitcoin address\n"
486 + HelpExampleCli("decoderawtransaction", "\"hexstring\"")
487 + HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
491 RPCTypeCheck(params, boost::assign::list_of(str_type));
495 if (!DecodeHexTx(tx, params[0].get_str()))
496 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
499 TxToJSON(tx, uint256(), result);
504 Value decodescript(const Array& params, bool fHelp)
506 if (fHelp || params.size() != 1)
508 "decodescript \"hex\"\n"
509 "\nDecode a hex-encoded script.\n"
511 "1. \"hex\" (string) the hex encoded script\n"
514 " \"asm\":\"asm\", (string) Script public key\n"
515 " \"hex\":\"hex\", (string) hex encoded public key\n"
516 " \"type\":\"type\", (string) The output type\n"
517 " \"reqSigs\": n, (numeric) The required signatures\n"
518 " \"addresses\": [ (json array of string)\n"
519 " \"address\" (string) bitcoin address\n"
522 " \"p2sh\",\"address\" (string) script address\n"
525 + HelpExampleCli("decodescript", "\"hexstring\"")
526 + HelpExampleRpc("decodescript", "\"hexstring\"")
530 RPCTypeCheck(params, boost::assign::list_of(str_type));
534 if (params[0].get_str().size() > 0){
535 vector<unsigned char> scriptData(ParseHexV(params[0], "argument"));
536 script = CScript(scriptData.begin(), scriptData.end());
538 // Empty scripts are valid
540 ScriptPubKeyToJSON(script, r, false);
542 r.push_back(Pair("p2sh", CBitcoinAddress(CScriptID(script)).ToString()));
546 /** Pushes a JSON object for script verification or signing errors to vErrorsRet. */
547 static void TxInErrorToJSON(const CTxIn& txin, Array& vErrorsRet, const std::string& strMessage)
550 entry.push_back(Pair("txid", txin.prevout.hash.ToString()));
551 entry.push_back(Pair("vout", (uint64_t)txin.prevout.n));
552 entry.push_back(Pair("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
553 entry.push_back(Pair("sequence", (uint64_t)txin.nSequence));
554 entry.push_back(Pair("error", strMessage));
555 vErrorsRet.push_back(entry);
558 Value signrawtransaction(const Array& params, bool fHelp)
560 if (fHelp || params.size() < 1 || params.size() > 4)
562 "signrawtransaction \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] [\"privatekey1\",...] sighashtype )\n"
563 "\nSign inputs for raw transaction (serialized, hex-encoded).\n"
564 "The second optional argument (may be null) is an array of previous transaction outputs that\n"
565 "this transaction depends on but may not yet be in the block chain.\n"
566 "The third optional argument (may be null) is an array of base58-encoded private\n"
567 "keys that, if given, will be the only keys used to sign the transaction.\n"
569 + HelpRequiringPassphrase() + "\n"
573 "1. \"hexstring\" (string, required) The transaction hex string\n"
574 "2. \"prevtxs\" (string, optional) An json array of previous dependent transaction outputs\n"
575 " [ (json array of json objects, or 'null' if none provided)\n"
577 " \"txid\":\"id\", (string, required) The transaction id\n"
578 " \"vout\":n, (numeric, required) The output number\n"
579 " \"scriptPubKey\": \"hex\", (string, required) script key\n"
580 " \"redeemScript\": \"hex\" (string, required for P2SH) redeem script\n"
584 "3. \"privatekeys\" (string, optional) A json array of base58-encoded private keys for signing\n"
585 " [ (json array of strings, or 'null' if none provided)\n"
586 " \"privatekey\" (string) private key in base58-encoding\n"
589 "4. \"sighashtype\" (string, optional, default=ALL) The signature hash type. Must be one of\n"
593 " \"ALL|ANYONECANPAY\"\n"
594 " \"NONE|ANYONECANPAY\"\n"
595 " \"SINGLE|ANYONECANPAY\"\n"
599 " \"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n"
600 " \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n"
601 " \"errors\" : [ (json array of objects) Script verification errors (if there are any)\n"
603 " \"txid\" : \"hash\", (string) The hash of the referenced, previous transaction\n"
604 " \"vout\" : n, (numeric) The index of the output to spent and used as input\n"
605 " \"scriptSig\" : \"hex\", (string) The hex-encoded signature script\n"
606 " \"sequence\" : n, (numeric) Script sequence number\n"
607 " \"error\" : \"text\" (string) Verification or signing error related to the input\n"
614 + HelpExampleCli("signrawtransaction", "\"myhex\"")
615 + HelpExampleRpc("signrawtransaction", "\"myhex\"")
619 LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
623 RPCTypeCheck(params, boost::assign::list_of(str_type)(array_type)(array_type)(str_type), true);
625 vector<unsigned char> txData(ParseHexV(params[0], "argument 1"));
626 CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
627 vector<CMutableTransaction> txVariants;
628 while (!ssData.empty()) {
630 CMutableTransaction tx;
632 txVariants.push_back(tx);
634 catch (const std::exception&) {
635 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
639 if (txVariants.empty())
640 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transaction");
642 // mergedTx will end up with all the signatures; it
643 // starts as a clone of the rawtx:
644 CMutableTransaction mergedTx(txVariants[0]);
646 // Fetch previous transactions (inputs):
647 CCoinsView viewDummy;
648 CCoinsViewCache view(&viewDummy);
651 CCoinsViewCache &viewChain = *pcoinsTip;
652 CCoinsViewMemPool viewMempool(&viewChain, mempool);
653 view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
655 BOOST_FOREACH(const CTxIn& txin, mergedTx.vin) {
656 const uint256& prevHash = txin.prevout.hash;
658 view.AccessCoins(prevHash); // this is certainly allowed to fail
661 view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
664 bool fGivenKeys = false;
665 CBasicKeyStore tempKeystore;
666 if (params.size() > 2 && params[2].type() != null_type) {
668 Array keys = params[2].get_array();
669 BOOST_FOREACH(Value k, keys) {
670 CBitcoinSecret vchSecret;
671 bool fGood = vchSecret.SetString(k.get_str());
673 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
674 CKey key = vchSecret.GetKey();
676 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
677 tempKeystore.AddKey(key);
681 else if (pwalletMain)
682 EnsureWalletIsUnlocked();
685 // Add previous txouts given in the RPC call:
686 if (params.size() > 1 && params[1].type() != null_type) {
687 Array prevTxs = params[1].get_array();
688 BOOST_FOREACH(Value& p, prevTxs) {
689 if (p.type() != obj_type)
690 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}");
692 Object prevOut = p.get_obj();
694 RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type));
696 uint256 txid = ParseHashO(prevOut, "txid");
698 int nOut = find_value(prevOut, "vout").get_int();
700 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout must be positive");
702 vector<unsigned char> pkData(ParseHexO(prevOut, "scriptPubKey"));
703 CScript scriptPubKey(pkData.begin(), pkData.end());
706 CCoinsModifier coins = view.ModifyCoins(txid);
707 if (coins->IsAvailable(nOut) && coins->vout[nOut].scriptPubKey != scriptPubKey) {
708 string err("Previous output scriptPubKey mismatch:\n");
709 err = err + coins->vout[nOut].scriptPubKey.ToString() + "\nvs:\n"+
710 scriptPubKey.ToString();
711 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err);
713 if ((unsigned int)nOut >= coins->vout.size())
714 coins->vout.resize(nOut+1);
715 coins->vout[nOut].scriptPubKey = scriptPubKey;
716 coins->vout[nOut].nValue = 0; // we don't know the actual output value
719 // if redeemScript given and not using the local wallet (private keys
720 // given), add redeemScript to the tempKeystore so it can be signed:
721 if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) {
722 RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)("redeemScript",str_type));
723 Value v = find_value(prevOut, "redeemScript");
724 if (!(v == Value::null)) {
725 vector<unsigned char> rsData(ParseHexV(v, "redeemScript"));
726 CScript redeemScript(rsData.begin(), rsData.end());
727 tempKeystore.AddCScript(redeemScript);
734 const CKeyStore& keystore = ((fGivenKeys || !pwalletMain) ? tempKeystore : *pwalletMain);
736 const CKeyStore& keystore = tempKeystore;
739 int nHashType = SIGHASH_ALL;
740 if (params.size() > 3 && params[3].type() != null_type) {
741 static map<string, int> mapSigHashValues =
742 boost::assign::map_list_of
743 (string("ALL"), int(SIGHASH_ALL))
744 (string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY))
745 (string("NONE"), int(SIGHASH_NONE))
746 (string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY))
747 (string("SINGLE"), int(SIGHASH_SINGLE))
748 (string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY))
750 string strHashType = params[3].get_str();
751 if (mapSigHashValues.count(strHashType))
752 nHashType = mapSigHashValues[strHashType];
754 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param");
757 bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
759 // Script verification errors
763 for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
764 CTxIn& txin = mergedTx.vin[i];
765 const CCoins* coins = view.AccessCoins(txin.prevout.hash);
766 if (coins == NULL || !coins->IsAvailable(txin.prevout.n)) {
767 TxInErrorToJSON(txin, vErrors, "Input not found or already spent");
770 const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey;
772 txin.scriptSig.clear();
773 // Only sign SIGHASH_SINGLE if there's a corresponding output:
774 if (!fHashSingle || (i < mergedTx.vout.size()))
775 SignSignature(keystore, prevPubKey, mergedTx, i, nHashType);
777 // ... and merge in other signatures:
778 BOOST_FOREACH(const CMutableTransaction& txv, txVariants) {
779 txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig);
781 ScriptError serror = SCRIPT_ERR_OK;
782 if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i), &serror)) {
783 TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror));
786 bool fComplete = vErrors.empty();
789 result.push_back(Pair("hex", EncodeHexTx(mergedTx)));
790 result.push_back(Pair("complete", fComplete));
791 if (!vErrors.empty()) {
792 result.push_back(Pair("errors", vErrors));
798 Value sendrawtransaction(const Array& params, bool fHelp)
800 if (fHelp || params.size() < 1 || params.size() > 2)
802 "sendrawtransaction \"hexstring\" ( allowhighfees )\n"
803 "\nSubmits raw transaction (serialized, hex-encoded) to local node and network.\n"
804 "\nAlso see createrawtransaction and signrawtransaction calls.\n"
806 "1. \"hexstring\" (string, required) The hex string of the raw transaction)\n"
807 "2. allowhighfees (boolean, optional, default=false) Allow high fees\n"
809 "\"hex\" (string) The transaction hash in hex\n"
811 "\nCreate a transaction\n"
812 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") +
813 "Sign the transaction, and get back the hex\n"
814 + HelpExampleCli("signrawtransaction", "\"myhex\"") +
815 "\nSend the transaction (signed hex)\n"
816 + HelpExampleCli("sendrawtransaction", "\"signedhex\"") +
817 "\nAs a json rpc call\n"
818 + HelpExampleRpc("sendrawtransaction", "\"signedhex\"")
822 RPCTypeCheck(params, boost::assign::list_of(str_type)(bool_type));
824 // parse hex string from parameter
826 if (!DecodeHexTx(tx, params[0].get_str()))
827 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
828 uint256 hashTx = tx.GetHash();
830 bool fOverrideFees = false;
831 if (params.size() > 1)
832 fOverrideFees = params[1].get_bool();
834 CCoinsViewCache &view = *pcoinsTip;
835 const CCoins* existingCoins = view.AccessCoins(hashTx);
836 bool fHaveMempool = mempool.exists(hashTx);
837 bool fHaveChain = existingCoins && existingCoins->nHeight < 1000000000;
838 if (!fHaveMempool && !fHaveChain) {
839 // push to local node and sync with wallets
840 CValidationState state;
842 if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees)) {
843 if (state.IsInvalid()) {
844 throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
846 if (fMissingInputs) {
847 throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs");
849 throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason());
852 } else if (fHaveChain) {
853 throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain");
855 RelayTransaction(tx);
857 return hashTx.GetHex();