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(int32_t txheight,uint64_t nValue,uint32_t nLockTime,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));
124 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
125 CBlockIndex *pindex = it->second;
127 for (unsigned int i = 0; i < tx.vout.size(); i++) {
128 const CTxOut& txout = tx.vout[i];
130 out.push_back(Pair("value", ValueFromAmount(txout.nValue)));
131 if ( pindex != 0 && tx.nLockTime != 0 )
133 interest = komodo_interest(pindex->nHeight,txout.nValue,tx.nLockTime,pindex->nTime);
134 //fprintf(stderr,"TxtoJSON interest %llu %.8f\n",(long long)interest,(double)interest/COIN);
135 out.push_back(Pair("interest", ValueFromAmount(interest)));
137 out.push_back(Pair("n", (int64_t)i));
139 ScriptPubKeyToJSON(txout.scriptPubKey, o, true);
140 out.push_back(Pair("scriptPubKey", o));
143 entry.push_back(Pair("vout", vout));
145 Array vjoinsplit = TxJoinSplitToJSON(tx);
146 entry.push_back(Pair("vjoinsplit", vjoinsplit));
148 if (!hashBlock.IsNull()) {
149 entry.push_back(Pair("blockhash", hashBlock.GetHex()));
150 BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
151 if (mi != mapBlockIndex.end() && (*mi).second) {
152 CBlockIndex* pindex = (*mi).second;
153 if (chainActive.Contains(pindex)) {
154 entry.push_back(Pair("confirmations", 1 + chainActive.Height() - pindex->nHeight));
155 entry.push_back(Pair("time", pindex->GetBlockTime()));
156 entry.push_back(Pair("blocktime", pindex->GetBlockTime()));
159 entry.push_back(Pair("confirmations", 0));
164 Value getrawtransaction(const Array& params, bool fHelp)
166 if (fHelp || params.size() < 1 || params.size() > 2)
168 "getrawtransaction \"txid\" ( verbose )\n"
169 "\nNOTE: By default this function only works sometimes. This is when the tx is in the mempool\n"
170 "or there is an unspent output in the utxo for this transaction. To make it always work,\n"
171 "you need to maintain a transaction index, using the -txindex command line option.\n"
172 "\nReturn the raw transaction data.\n"
173 "\nIf verbose=0, returns a string that is serialized, hex-encoded data for 'txid'.\n"
174 "If verbose is non-zero, returns an Object with information about 'txid'.\n"
177 "1. \"txid\" (string, required) The transaction id\n"
178 "2. verbose (numeric, optional, default=0) If 0, return a string, other return a json object\n"
180 "\nResult (if verbose is not set or set to 0):\n"
181 "\"data\" (string) The serialized, hex-encoded data for 'txid'\n"
183 "\nResult (if verbose > 0):\n"
185 " \"hex\" : \"data\", (string) The serialized, hex-encoded data for 'txid'\n"
186 " \"txid\" : \"id\", (string) The transaction id (same as provided)\n"
187 " \"version\" : n, (numeric) The version\n"
188 " \"locktime\" : ttt, (numeric) The lock time\n"
189 " \"vin\" : [ (array of json objects)\n"
191 " \"txid\": \"id\", (string) The transaction id\n"
192 " \"vout\": n, (numeric) \n"
193 " \"scriptSig\": { (json object) The script\n"
194 " \"asm\": \"asm\", (string) asm\n"
195 " \"hex\": \"hex\" (string) hex\n"
197 " \"sequence\": n (numeric) The script sequence number\n"
201 " \"vout\" : [ (array of json objects)\n"
203 " \"value\" : x.xxx, (numeric) The value in btc\n"
204 " \"n\" : n, (numeric) index\n"
205 " \"scriptPubKey\" : { (json object)\n"
206 " \"asm\" : \"asm\", (string) the asm\n"
207 " \"hex\" : \"hex\", (string) the hex\n"
208 " \"reqSigs\" : n, (numeric) The required sigs\n"
209 " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
210 " \"addresses\" : [ (json array of string)\n"
211 " \"bitcoinaddress\" (string) bitcoin address\n"
218 " \"blockhash\" : \"hash\", (string) the block hash\n"
219 " \"confirmations\" : n, (numeric) The confirmations\n"
220 " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT)\n"
221 " \"blocktime\" : ttt (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
225 + HelpExampleCli("getrawtransaction", "\"mytxid\"")
226 + HelpExampleCli("getrawtransaction", "\"mytxid\" 1")
227 + HelpExampleRpc("getrawtransaction", "\"mytxid\", 1")
232 uint256 hash = ParseHashV(params[0], "parameter 1");
234 bool fVerbose = false;
235 if (params.size() > 1)
236 fVerbose = (params[1].get_int() != 0);
240 if (!GetTransaction(hash, tx, hashBlock, true))
241 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction");
243 string strHex = EncodeHexTx(tx);
249 result.push_back(Pair("hex", strHex));
250 TxToJSON(tx, hashBlock, result);
254 Value gettxoutproof(const Array& params, bool fHelp)
256 if (fHelp || (params.size() != 1 && params.size() != 2))
258 "gettxoutproof [\"txid\",...] ( blockhash )\n"
259 "\nReturns a hex-encoded proof that \"txid\" was included in a block.\n"
260 "\nNOTE: By default this function only works sometimes. This is when there is an\n"
261 "unspent output in the utxo for this transaction. To make it always work,\n"
262 "you need to maintain a transaction index, using the -txindex command line option or\n"
263 "specify the block in which the transaction is included in manually (by blockhash).\n"
264 "\nReturn the raw transaction data.\n"
266 "1. \"txids\" (string) A json array of txids to filter\n"
268 " \"txid\" (string) A transaction hash\n"
271 "2. \"block hash\" (string, optional) If specified, looks for txid in the block with this hash\n"
273 "\"data\" (string) A string that is a serialized, hex-encoded data for the proof.\n"
276 set<uint256> setTxids;
278 Array txids = params[0].get_array();
279 BOOST_FOREACH(Value& txid, txids) {
280 if (txid.get_str().length() != 64 || !IsHex(txid.get_str()))
281 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid txid ")+txid.get_str());
282 uint256 hash(uint256S(txid.get_str()));
283 if (setTxids.count(hash))
284 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated txid: ")+txid.get_str());
285 setTxids.insert(hash);
291 CBlockIndex* pblockindex = NULL;
294 if (params.size() > 1)
296 hashBlock = uint256S(params[1].get_str());
297 if (!mapBlockIndex.count(hashBlock))
298 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
299 pblockindex = mapBlockIndex[hashBlock];
302 if (pcoinsTip->GetCoins(oneTxid, coins) && coins.nHeight > 0 && coins.nHeight <= chainActive.Height())
303 pblockindex = chainActive[coins.nHeight];
306 if (pblockindex == NULL)
309 if (!GetTransaction(oneTxid, tx, hashBlock, false) || hashBlock.IsNull())
310 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block");
311 if (!mapBlockIndex.count(hashBlock))
312 throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt");
313 pblockindex = mapBlockIndex[hashBlock];
317 if(!ReadBlockFromDisk(block, pblockindex))
318 throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
320 unsigned int ntxFound = 0;
321 BOOST_FOREACH(const CTransaction&tx, block.vtx)
322 if (setTxids.count(tx.GetHash()))
324 if (ntxFound != setTxids.size())
325 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "(Not all) transactions not found in specified block");
327 CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION);
328 CMerkleBlock mb(block, setTxids);
330 std::string strHex = HexStr(ssMB.begin(), ssMB.end());
334 Value verifytxoutproof(const Array& params, bool fHelp)
336 if (fHelp || params.size() != 1)
338 "verifytxoutproof \"proof\"\n"
339 "\nVerifies that a proof points to a transaction in a block, returning the transaction it commits to\n"
340 "and throwing an RPC error if the block is not in our best chain\n"
342 "1. \"proof\" (string, required) The hex-encoded proof generated by gettxoutproof\n"
344 "[\"txid\"] (array, strings) The txid(s) which the proof commits to, or empty array if the proof is invalid\n"
347 CDataStream ssMB(ParseHexV(params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION);
348 CMerkleBlock merkleBlock;
353 vector<uint256> vMatch;
354 if (merkleBlock.txn.ExtractMatches(vMatch) != merkleBlock.header.hashMerkleRoot)
359 if (!mapBlockIndex.count(merkleBlock.header.GetHash()) || !chainActive.Contains(mapBlockIndex[merkleBlock.header.GetHash()]))
360 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain");
362 BOOST_FOREACH(const uint256& hash, vMatch)
363 res.push_back(hash.GetHex());
367 Value createrawtransaction(const Array& params, bool fHelp)
369 if (fHelp || params.size() != 2)
371 "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,...}\n"
372 "\nCreate a transaction spending the given inputs and sending to the given addresses.\n"
373 "Returns hex-encoded raw transaction.\n"
374 "Note that the transaction's inputs are not signed, and\n"
375 "it is not stored in the wallet or transmitted to the network.\n"
378 "1. \"transactions\" (string, required) A json array of json objects\n"
381 " \"txid\":\"id\", (string, required) The transaction id\n"
382 " \"vout\":n (numeric, required) The output number\n"
386 "2. \"addresses\" (string, required) a json object with addresses as keys and amounts as values\n"
388 " \"address\": x.xxx (numeric, required) The key is the bitcoin address, the value is the btc amount\n"
393 "\"transaction\" (string) hex string of the transaction\n"
396 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":0.01}\"")
397 + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\"")
401 RPCTypeCheck(params, boost::assign::list_of(array_type)(obj_type));
403 Array inputs = params[0].get_array();
404 Object sendTo = params[1].get_obj();
406 CMutableTransaction rawTx;
408 BOOST_FOREACH(const Value& input, inputs) {
409 const Object& o = input.get_obj();
411 uint256 txid = ParseHashO(o, "txid");
413 const Value& vout_v = find_value(o, "vout");
414 if (vout_v.type() != int_type)
415 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");
416 int nOutput = vout_v.get_int();
418 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
420 CTxIn in(COutPoint(txid, nOutput));
421 rawTx.vin.push_back(in);
424 set<CBitcoinAddress> setAddress;
425 BOOST_FOREACH(const Pair& s, sendTo) {
426 CBitcoinAddress address(s.name_);
427 if (!address.IsValid())
428 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+s.name_);
430 if (setAddress.count(address))
431 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_);
432 setAddress.insert(address);
434 CScript scriptPubKey = GetScriptForDestination(address.Get());
435 CAmount nAmount = AmountFromValue(s.value_);
437 CTxOut out(nAmount, scriptPubKey);
438 rawTx.vout.push_back(out);
441 return EncodeHexTx(rawTx);
444 Value decoderawtransaction(const Array& params, bool fHelp)
446 if (fHelp || params.size() != 1)
448 "decoderawtransaction \"hexstring\"\n"
449 "\nReturn a JSON object representing the serialized, hex-encoded transaction.\n"
452 "1. \"hex\" (string, required) The transaction hex string\n"
456 " \"txid\" : \"id\", (string) The transaction id\n"
457 " \"version\" : n, (numeric) The version\n"
458 " \"locktime\" : ttt, (numeric) The lock time\n"
459 " \"vin\" : [ (array of json objects)\n"
461 " \"txid\": \"id\", (string) The transaction id\n"
462 " \"vout\": n, (numeric) The output number\n"
463 " \"scriptSig\": { (json object) The script\n"
464 " \"asm\": \"asm\", (string) asm\n"
465 " \"hex\": \"hex\" (string) hex\n"
467 " \"sequence\": n (numeric) The script sequence number\n"
471 " \"vout\" : [ (array of json objects)\n"
473 " \"value\" : x.xxx, (numeric) The value in btc\n"
474 " \"n\" : n, (numeric) index\n"
475 " \"scriptPubKey\" : { (json object)\n"
476 " \"asm\" : \"asm\", (string) the asm\n"
477 " \"hex\" : \"hex\", (string) the hex\n"
478 " \"reqSigs\" : n, (numeric) The required sigs\n"
479 " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
480 " \"addresses\" : [ (json array of string)\n"
481 " \"12tvKAXCxZjSmdNbao16dKXC8tRWfcF5oc\" (string) bitcoin address\n"
491 + HelpExampleCli("decoderawtransaction", "\"hexstring\"")
492 + HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
496 RPCTypeCheck(params, boost::assign::list_of(str_type));
500 if (!DecodeHexTx(tx, params[0].get_str()))
501 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
504 TxToJSON(tx, uint256(), result);
509 Value decodescript(const Array& params, bool fHelp)
511 if (fHelp || params.size() != 1)
513 "decodescript \"hex\"\n"
514 "\nDecode a hex-encoded script.\n"
516 "1. \"hex\" (string) the hex encoded script\n"
519 " \"asm\":\"asm\", (string) Script public key\n"
520 " \"hex\":\"hex\", (string) hex encoded public key\n"
521 " \"type\":\"type\", (string) The output type\n"
522 " \"reqSigs\": n, (numeric) The required signatures\n"
523 " \"addresses\": [ (json array of string)\n"
524 " \"address\" (string) bitcoin address\n"
527 " \"p2sh\",\"address\" (string) script address\n"
530 + HelpExampleCli("decodescript", "\"hexstring\"")
531 + HelpExampleRpc("decodescript", "\"hexstring\"")
535 RPCTypeCheck(params, boost::assign::list_of(str_type));
539 if (params[0].get_str().size() > 0){
540 vector<unsigned char> scriptData(ParseHexV(params[0], "argument"));
541 script = CScript(scriptData.begin(), scriptData.end());
543 // Empty scripts are valid
545 ScriptPubKeyToJSON(script, r, false);
547 r.push_back(Pair("p2sh", CBitcoinAddress(CScriptID(script)).ToString()));
551 /** Pushes a JSON object for script verification or signing errors to vErrorsRet. */
552 static void TxInErrorToJSON(const CTxIn& txin, Array& vErrorsRet, const std::string& strMessage)
555 entry.push_back(Pair("txid", txin.prevout.hash.ToString()));
556 entry.push_back(Pair("vout", (uint64_t)txin.prevout.n));
557 entry.push_back(Pair("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
558 entry.push_back(Pair("sequence", (uint64_t)txin.nSequence));
559 entry.push_back(Pair("error", strMessage));
560 vErrorsRet.push_back(entry);
563 Value signrawtransaction(const Array& params, bool fHelp)
565 if (fHelp || params.size() < 1 || params.size() > 4)
567 "signrawtransaction \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] [\"privatekey1\",...] sighashtype )\n"
568 "\nSign inputs for raw transaction (serialized, hex-encoded).\n"
569 "The second optional argument (may be null) is an array of previous transaction outputs that\n"
570 "this transaction depends on but may not yet be in the block chain.\n"
571 "The third optional argument (may be null) is an array of base58-encoded private\n"
572 "keys that, if given, will be the only keys used to sign the transaction.\n"
574 + HelpRequiringPassphrase() + "\n"
578 "1. \"hexstring\" (string, required) The transaction hex string\n"
579 "2. \"prevtxs\" (string, optional) An json array of previous dependent transaction outputs\n"
580 " [ (json array of json objects, or 'null' if none provided)\n"
582 " \"txid\":\"id\", (string, required) The transaction id\n"
583 " \"vout\":n, (numeric, required) The output number\n"
584 " \"scriptPubKey\": \"hex\", (string, required) script key\n"
585 " \"redeemScript\": \"hex\" (string, required for P2SH) redeem script\n"
589 "3. \"privatekeys\" (string, optional) A json array of base58-encoded private keys for signing\n"
590 " [ (json array of strings, or 'null' if none provided)\n"
591 " \"privatekey\" (string) private key in base58-encoding\n"
594 "4. \"sighashtype\" (string, optional, default=ALL) The signature hash type. Must be one of\n"
598 " \"ALL|ANYONECANPAY\"\n"
599 " \"NONE|ANYONECANPAY\"\n"
600 " \"SINGLE|ANYONECANPAY\"\n"
604 " \"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n"
605 " \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n"
606 " \"errors\" : [ (json array of objects) Script verification errors (if there are any)\n"
608 " \"txid\" : \"hash\", (string) The hash of the referenced, previous transaction\n"
609 " \"vout\" : n, (numeric) The index of the output to spent and used as input\n"
610 " \"scriptSig\" : \"hex\", (string) The hex-encoded signature script\n"
611 " \"sequence\" : n, (numeric) Script sequence number\n"
612 " \"error\" : \"text\" (string) Verification or signing error related to the input\n"
619 + HelpExampleCli("signrawtransaction", "\"myhex\"")
620 + HelpExampleRpc("signrawtransaction", "\"myhex\"")
624 LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
628 RPCTypeCheck(params, boost::assign::list_of(str_type)(array_type)(array_type)(str_type), true);
630 vector<unsigned char> txData(ParseHexV(params[0], "argument 1"));
631 CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
632 vector<CMutableTransaction> txVariants;
633 while (!ssData.empty()) {
635 CMutableTransaction tx;
637 txVariants.push_back(tx);
639 catch (const std::exception&) {
640 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
644 if (txVariants.empty())
645 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transaction");
647 // mergedTx will end up with all the signatures; it
648 // starts as a clone of the rawtx:
649 CMutableTransaction mergedTx(txVariants[0]);
651 // Fetch previous transactions (inputs):
652 CCoinsView viewDummy;
653 CCoinsViewCache view(&viewDummy);
656 CCoinsViewCache &viewChain = *pcoinsTip;
657 CCoinsViewMemPool viewMempool(&viewChain, mempool);
658 view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
660 BOOST_FOREACH(const CTxIn& txin, mergedTx.vin) {
661 const uint256& prevHash = txin.prevout.hash;
663 view.AccessCoins(prevHash); // this is certainly allowed to fail
666 view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
669 bool fGivenKeys = false;
670 CBasicKeyStore tempKeystore;
671 if (params.size() > 2 && params[2].type() != null_type) {
673 Array keys = params[2].get_array();
674 BOOST_FOREACH(Value k, keys) {
675 CBitcoinSecret vchSecret;
676 bool fGood = vchSecret.SetString(k.get_str());
678 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
679 CKey key = vchSecret.GetKey();
681 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
682 tempKeystore.AddKey(key);
686 else if (pwalletMain)
687 EnsureWalletIsUnlocked();
690 // Add previous txouts given in the RPC call:
691 if (params.size() > 1 && params[1].type() != null_type) {
692 Array prevTxs = params[1].get_array();
693 BOOST_FOREACH(Value& p, prevTxs) {
694 if (p.type() != obj_type)
695 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}");
697 Object prevOut = p.get_obj();
699 RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type));
701 uint256 txid = ParseHashO(prevOut, "txid");
703 int nOut = find_value(prevOut, "vout").get_int();
705 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout must be positive");
707 vector<unsigned char> pkData(ParseHexO(prevOut, "scriptPubKey"));
708 CScript scriptPubKey(pkData.begin(), pkData.end());
711 CCoinsModifier coins = view.ModifyCoins(txid);
712 if (coins->IsAvailable(nOut) && coins->vout[nOut].scriptPubKey != scriptPubKey) {
713 string err("Previous output scriptPubKey mismatch:\n");
714 err = err + coins->vout[nOut].scriptPubKey.ToString() + "\nvs:\n"+
715 scriptPubKey.ToString();
716 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err);
718 if ((unsigned int)nOut >= coins->vout.size())
719 coins->vout.resize(nOut+1);
720 coins->vout[nOut].scriptPubKey = scriptPubKey;
721 coins->vout[nOut].nValue = 0; // we don't know the actual output value
724 // if redeemScript given and not using the local wallet (private keys
725 // given), add redeemScript to the tempKeystore so it can be signed:
726 if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) {
727 RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)("redeemScript",str_type));
728 Value v = find_value(prevOut, "redeemScript");
729 if (!(v == Value::null)) {
730 vector<unsigned char> rsData(ParseHexV(v, "redeemScript"));
731 CScript redeemScript(rsData.begin(), rsData.end());
732 tempKeystore.AddCScript(redeemScript);
739 const CKeyStore& keystore = ((fGivenKeys || !pwalletMain) ? tempKeystore : *pwalletMain);
741 const CKeyStore& keystore = tempKeystore;
744 int nHashType = SIGHASH_ALL;
745 if (params.size() > 3 && params[3].type() != null_type) {
746 static map<string, int> mapSigHashValues =
747 boost::assign::map_list_of
748 (string("ALL"), int(SIGHASH_ALL))
749 (string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY))
750 (string("NONE"), int(SIGHASH_NONE))
751 (string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY))
752 (string("SINGLE"), int(SIGHASH_SINGLE))
753 (string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY))
755 string strHashType = params[3].get_str();
756 if (mapSigHashValues.count(strHashType))
757 nHashType = mapSigHashValues[strHashType];
759 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param");
762 bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
764 // Script verification errors
768 for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
769 CTxIn& txin = mergedTx.vin[i];
770 const CCoins* coins = view.AccessCoins(txin.prevout.hash);
771 if (coins == NULL || !coins->IsAvailable(txin.prevout.n)) {
772 TxInErrorToJSON(txin, vErrors, "Input not found or already spent");
775 const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey;
777 txin.scriptSig.clear();
778 // Only sign SIGHASH_SINGLE if there's a corresponding output:
779 if (!fHashSingle || (i < mergedTx.vout.size()))
780 SignSignature(keystore, prevPubKey, mergedTx, i, nHashType);
782 // ... and merge in other signatures:
783 BOOST_FOREACH(const CMutableTransaction& txv, txVariants) {
784 txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig);
786 ScriptError serror = SCRIPT_ERR_OK;
787 if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i), &serror)) {
788 TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror));
791 bool fComplete = vErrors.empty();
794 result.push_back(Pair("hex", EncodeHexTx(mergedTx)));
795 result.push_back(Pair("complete", fComplete));
796 if (!vErrors.empty()) {
797 result.push_back(Pair("errors", vErrors));
803 Value sendrawtransaction(const Array& params, bool fHelp)
805 if (fHelp || params.size() < 1 || params.size() > 2)
807 "sendrawtransaction \"hexstring\" ( allowhighfees )\n"
808 "\nSubmits raw transaction (serialized, hex-encoded) to local node and network.\n"
809 "\nAlso see createrawtransaction and signrawtransaction calls.\n"
811 "1. \"hexstring\" (string, required) The hex string of the raw transaction)\n"
812 "2. allowhighfees (boolean, optional, default=false) Allow high fees\n"
814 "\"hex\" (string) The transaction hash in hex\n"
816 "\nCreate a transaction\n"
817 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") +
818 "Sign the transaction, and get back the hex\n"
819 + HelpExampleCli("signrawtransaction", "\"myhex\"") +
820 "\nSend the transaction (signed hex)\n"
821 + HelpExampleCli("sendrawtransaction", "\"signedhex\"") +
822 "\nAs a json rpc call\n"
823 + HelpExampleRpc("sendrawtransaction", "\"signedhex\"")
827 RPCTypeCheck(params, boost::assign::list_of(str_type)(bool_type));
829 // parse hex string from parameter
831 if (!DecodeHexTx(tx, params[0].get_str()))
832 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
833 uint256 hashTx = tx.GetHash();
835 bool fOverrideFees = false;
836 if (params.size() > 1)
837 fOverrideFees = params[1].get_bool();
839 CCoinsViewCache &view = *pcoinsTip;
840 const CCoins* existingCoins = view.AccessCoins(hashTx);
841 bool fHaveMempool = mempool.exists(hashTx);
842 bool fHaveChain = existingCoins && existingCoins->nHeight < 1000000000;
843 if (!fHaveMempool && !fHaveChain) {
844 // push to local node and sync with wallets
845 CValidationState state;
847 if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees)) {
848 if (state.IsInvalid()) {
849 throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
851 if (fMissingInputs) {
852 throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs");
854 throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason());
857 } else if (fHaveChain) {
858 throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain");
860 RelayTransaction(tx);
862 return hashTx.GetHex();