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 *tipindex,*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 && (tipindex= chainActive.Tip()) != 0 )
133 extern char ASSETCHAINS_SYMBOL[16];
134 interest = komodo_interest(pindex->nHeight,txout.nValue,tx.nLockTime,tipindex->nTime);
135 if ( strcmp("REVS",ASSETCHAINS_SYMBOL) == 0 )
136 fprintf(stderr,"TxtoJSON interest %llu %.8f (%d %llu %u %u)\n",(long long)interest,(double)interest/COIN,(int32_t)pindex->nHeight,(long long)txout.nValue,(uint32_t)tx.nLockTime,(int32_t)tipindex->nTime);
137 out.push_back(Pair("interest", ValueFromAmount(interest)));
139 out.push_back(Pair("n", (int64_t)i));
141 ScriptPubKeyToJSON(txout.scriptPubKey, o, true);
142 out.push_back(Pair("scriptPubKey", o));
145 entry.push_back(Pair("vout", vout));
147 Array vjoinsplit = TxJoinSplitToJSON(tx);
148 entry.push_back(Pair("vjoinsplit", vjoinsplit));
150 if (!hashBlock.IsNull()) {
151 entry.push_back(Pair("blockhash", hashBlock.GetHex()));
152 BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
153 if (mi != mapBlockIndex.end() && (*mi).second) {
154 CBlockIndex* pindex = (*mi).second;
155 if (chainActive.Contains(pindex)) {
156 entry.push_back(Pair("confirmations", 1 + chainActive.Height() - pindex->nHeight));
157 entry.push_back(Pair("time", pindex->GetBlockTime()));
158 entry.push_back(Pair("blocktime", pindex->GetBlockTime()));
161 entry.push_back(Pair("confirmations", 0));
166 Value getrawtransaction(const Array& params, bool fHelp)
168 if (fHelp || params.size() < 1 || params.size() > 2)
170 "getrawtransaction \"txid\" ( verbose )\n"
171 "\nNOTE: By default this function only works sometimes. This is when the tx is in the mempool\n"
172 "or there is an unspent output in the utxo for this transaction. To make it always work,\n"
173 "you need to maintain a transaction index, using the -txindex command line option.\n"
174 "\nReturn the raw transaction data.\n"
175 "\nIf verbose=0, returns a string that is serialized, hex-encoded data for 'txid'.\n"
176 "If verbose is non-zero, returns an Object with information about 'txid'.\n"
179 "1. \"txid\" (string, required) The transaction id\n"
180 "2. verbose (numeric, optional, default=0) If 0, return a string, other return a json object\n"
182 "\nResult (if verbose is not set or set to 0):\n"
183 "\"data\" (string) The serialized, hex-encoded data for 'txid'\n"
185 "\nResult (if verbose > 0):\n"
187 " \"hex\" : \"data\", (string) The serialized, hex-encoded data for 'txid'\n"
188 " \"txid\" : \"id\", (string) The transaction id (same as provided)\n"
189 " \"version\" : n, (numeric) The version\n"
190 " \"locktime\" : ttt, (numeric) The lock time\n"
191 " \"vin\" : [ (array of json objects)\n"
193 " \"txid\": \"id\", (string) The transaction id\n"
194 " \"vout\": n, (numeric) \n"
195 " \"scriptSig\": { (json object) The script\n"
196 " \"asm\": \"asm\", (string) asm\n"
197 " \"hex\": \"hex\" (string) hex\n"
199 " \"sequence\": n (numeric) The script sequence number\n"
203 " \"vout\" : [ (array of json objects)\n"
205 " \"value\" : x.xxx, (numeric) The value in btc\n"
206 " \"n\" : n, (numeric) index\n"
207 " \"scriptPubKey\" : { (json object)\n"
208 " \"asm\" : \"asm\", (string) the asm\n"
209 " \"hex\" : \"hex\", (string) the hex\n"
210 " \"reqSigs\" : n, (numeric) The required sigs\n"
211 " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
212 " \"addresses\" : [ (json array of string)\n"
213 " \"bitcoinaddress\" (string) bitcoin address\n"
220 " \"blockhash\" : \"hash\", (string) the block hash\n"
221 " \"confirmations\" : n, (numeric) The confirmations\n"
222 " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT)\n"
223 " \"blocktime\" : ttt (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
227 + HelpExampleCli("getrawtransaction", "\"mytxid\"")
228 + HelpExampleCli("getrawtransaction", "\"mytxid\" 1")
229 + HelpExampleRpc("getrawtransaction", "\"mytxid\", 1")
234 uint256 hash = ParseHashV(params[0], "parameter 1");
236 bool fVerbose = false;
237 if (params.size() > 1)
238 fVerbose = (params[1].get_int() != 0);
242 if (!GetTransaction(hash, tx, hashBlock, true))
243 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction");
245 string strHex = EncodeHexTx(tx);
251 result.push_back(Pair("hex", strHex));
252 TxToJSON(tx, hashBlock, result);
256 Value gettxoutproof(const Array& params, bool fHelp)
258 if (fHelp || (params.size() != 1 && params.size() != 2))
260 "gettxoutproof [\"txid\",...] ( blockhash )\n"
261 "\nReturns a hex-encoded proof that \"txid\" was included in a block.\n"
262 "\nNOTE: By default this function only works sometimes. This is when there is an\n"
263 "unspent output in the utxo for this transaction. To make it always work,\n"
264 "you need to maintain a transaction index, using the -txindex command line option or\n"
265 "specify the block in which the transaction is included in manually (by blockhash).\n"
266 "\nReturn the raw transaction data.\n"
268 "1. \"txids\" (string) A json array of txids to filter\n"
270 " \"txid\" (string) A transaction hash\n"
273 "2. \"block hash\" (string, optional) If specified, looks for txid in the block with this hash\n"
275 "\"data\" (string) A string that is a serialized, hex-encoded data for the proof.\n"
278 set<uint256> setTxids;
280 Array txids = params[0].get_array();
281 BOOST_FOREACH(Value& txid, txids) {
282 if (txid.get_str().length() != 64 || !IsHex(txid.get_str()))
283 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid txid ")+txid.get_str());
284 uint256 hash(uint256S(txid.get_str()));
285 if (setTxids.count(hash))
286 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated txid: ")+txid.get_str());
287 setTxids.insert(hash);
293 CBlockIndex* pblockindex = NULL;
296 if (params.size() > 1)
298 hashBlock = uint256S(params[1].get_str());
299 if (!mapBlockIndex.count(hashBlock))
300 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
301 pblockindex = mapBlockIndex[hashBlock];
304 if (pcoinsTip->GetCoins(oneTxid, coins) && coins.nHeight > 0 && coins.nHeight <= chainActive.Height())
305 pblockindex = chainActive[coins.nHeight];
308 if (pblockindex == NULL)
311 if (!GetTransaction(oneTxid, tx, hashBlock, false) || hashBlock.IsNull())
312 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block");
313 if (!mapBlockIndex.count(hashBlock))
314 throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt");
315 pblockindex = mapBlockIndex[hashBlock];
319 if(!ReadBlockFromDisk(block, pblockindex))
320 throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
322 unsigned int ntxFound = 0;
323 BOOST_FOREACH(const CTransaction&tx, block.vtx)
324 if (setTxids.count(tx.GetHash()))
326 if (ntxFound != setTxids.size())
327 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "(Not all) transactions not found in specified block");
329 CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION);
330 CMerkleBlock mb(block, setTxids);
332 std::string strHex = HexStr(ssMB.begin(), ssMB.end());
336 Value verifytxoutproof(const Array& params, bool fHelp)
338 if (fHelp || params.size() != 1)
340 "verifytxoutproof \"proof\"\n"
341 "\nVerifies that a proof points to a transaction in a block, returning the transaction it commits to\n"
342 "and throwing an RPC error if the block is not in our best chain\n"
344 "1. \"proof\" (string, required) The hex-encoded proof generated by gettxoutproof\n"
346 "[\"txid\"] (array, strings) The txid(s) which the proof commits to, or empty array if the proof is invalid\n"
349 CDataStream ssMB(ParseHexV(params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION);
350 CMerkleBlock merkleBlock;
355 vector<uint256> vMatch;
356 if (merkleBlock.txn.ExtractMatches(vMatch) != merkleBlock.header.hashMerkleRoot)
361 if (!mapBlockIndex.count(merkleBlock.header.GetHash()) || !chainActive.Contains(mapBlockIndex[merkleBlock.header.GetHash()]))
362 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain");
364 BOOST_FOREACH(const uint256& hash, vMatch)
365 res.push_back(hash.GetHex());
369 Value createrawtransaction(const Array& params, bool fHelp)
371 if (fHelp || params.size() != 2)
373 "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,...}\n"
374 "\nCreate a transaction spending the given inputs and sending to the given addresses.\n"
375 "Returns hex-encoded raw transaction.\n"
376 "Note that the transaction's inputs are not signed, and\n"
377 "it is not stored in the wallet or transmitted to the network.\n"
380 "1. \"transactions\" (string, required) A json array of json objects\n"
383 " \"txid\":\"id\", (string, required) The transaction id\n"
384 " \"vout\":n (numeric, required) The output number\n"
388 "2. \"addresses\" (string, required) a json object with addresses as keys and amounts as values\n"
390 " \"address\": x.xxx (numeric, required) The key is the bitcoin address, the value is the btc amount\n"
395 "\"transaction\" (string) hex string of the transaction\n"
398 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":0.01}\"")
399 + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\"")
403 RPCTypeCheck(params, boost::assign::list_of(array_type)(obj_type));
405 Array inputs = params[0].get_array();
406 Object sendTo = params[1].get_obj();
408 CMutableTransaction rawTx;
410 BOOST_FOREACH(const Value& input, inputs) {
411 const Object& o = input.get_obj();
413 uint256 txid = ParseHashO(o, "txid");
415 const Value& vout_v = find_value(o, "vout");
416 if (vout_v.type() != int_type)
417 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");
418 int nOutput = vout_v.get_int();
420 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
422 CTxIn in(COutPoint(txid, nOutput));
423 rawTx.vin.push_back(in);
426 set<CBitcoinAddress> setAddress;
427 BOOST_FOREACH(const Pair& s, sendTo) {
428 CBitcoinAddress address(s.name_);
429 if (!address.IsValid())
430 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+s.name_);
432 if (setAddress.count(address))
433 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_);
434 setAddress.insert(address);
436 CScript scriptPubKey = GetScriptForDestination(address.Get());
437 CAmount nAmount = AmountFromValue(s.value_);
439 CTxOut out(nAmount, scriptPubKey);
440 rawTx.vout.push_back(out);
443 return EncodeHexTx(rawTx);
446 Value decoderawtransaction(const Array& params, bool fHelp)
448 if (fHelp || params.size() != 1)
450 "decoderawtransaction \"hexstring\"\n"
451 "\nReturn a JSON object representing the serialized, hex-encoded transaction.\n"
454 "1. \"hex\" (string, required) The transaction hex string\n"
458 " \"txid\" : \"id\", (string) The transaction id\n"
459 " \"version\" : n, (numeric) The version\n"
460 " \"locktime\" : ttt, (numeric) The lock time\n"
461 " \"vin\" : [ (array of json objects)\n"
463 " \"txid\": \"id\", (string) The transaction id\n"
464 " \"vout\": n, (numeric) The output number\n"
465 " \"scriptSig\": { (json object) The script\n"
466 " \"asm\": \"asm\", (string) asm\n"
467 " \"hex\": \"hex\" (string) hex\n"
469 " \"sequence\": n (numeric) The script sequence number\n"
473 " \"vout\" : [ (array of json objects)\n"
475 " \"value\" : x.xxx, (numeric) The value in btc\n"
476 " \"n\" : n, (numeric) index\n"
477 " \"scriptPubKey\" : { (json object)\n"
478 " \"asm\" : \"asm\", (string) the asm\n"
479 " \"hex\" : \"hex\", (string) the hex\n"
480 " \"reqSigs\" : n, (numeric) The required sigs\n"
481 " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
482 " \"addresses\" : [ (json array of string)\n"
483 " \"12tvKAXCxZjSmdNbao16dKXC8tRWfcF5oc\" (string) bitcoin address\n"
493 + HelpExampleCli("decoderawtransaction", "\"hexstring\"")
494 + HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
498 RPCTypeCheck(params, boost::assign::list_of(str_type));
502 if (!DecodeHexTx(tx, params[0].get_str()))
503 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
506 TxToJSON(tx, uint256(), result);
511 Value decodescript(const Array& params, bool fHelp)
513 if (fHelp || params.size() != 1)
515 "decodescript \"hex\"\n"
516 "\nDecode a hex-encoded script.\n"
518 "1. \"hex\" (string) the hex encoded script\n"
521 " \"asm\":\"asm\", (string) Script public key\n"
522 " \"hex\":\"hex\", (string) hex encoded public key\n"
523 " \"type\":\"type\", (string) The output type\n"
524 " \"reqSigs\": n, (numeric) The required signatures\n"
525 " \"addresses\": [ (json array of string)\n"
526 " \"address\" (string) bitcoin address\n"
529 " \"p2sh\",\"address\" (string) script address\n"
532 + HelpExampleCli("decodescript", "\"hexstring\"")
533 + HelpExampleRpc("decodescript", "\"hexstring\"")
537 RPCTypeCheck(params, boost::assign::list_of(str_type));
541 if (params[0].get_str().size() > 0){
542 vector<unsigned char> scriptData(ParseHexV(params[0], "argument"));
543 script = CScript(scriptData.begin(), scriptData.end());
545 // Empty scripts are valid
547 ScriptPubKeyToJSON(script, r, false);
549 r.push_back(Pair("p2sh", CBitcoinAddress(CScriptID(script)).ToString()));
553 /** Pushes a JSON object for script verification or signing errors to vErrorsRet. */
554 static void TxInErrorToJSON(const CTxIn& txin, Array& vErrorsRet, const std::string& strMessage)
557 entry.push_back(Pair("txid", txin.prevout.hash.ToString()));
558 entry.push_back(Pair("vout", (uint64_t)txin.prevout.n));
559 entry.push_back(Pair("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
560 entry.push_back(Pair("sequence", (uint64_t)txin.nSequence));
561 entry.push_back(Pair("error", strMessage));
562 vErrorsRet.push_back(entry);
565 Value signrawtransaction(const Array& params, bool fHelp)
567 if (fHelp || params.size() < 1 || params.size() > 4)
569 "signrawtransaction \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] [\"privatekey1\",...] sighashtype )\n"
570 "\nSign inputs for raw transaction (serialized, hex-encoded).\n"
571 "The second optional argument (may be null) is an array of previous transaction outputs that\n"
572 "this transaction depends on but may not yet be in the block chain.\n"
573 "The third optional argument (may be null) is an array of base58-encoded private\n"
574 "keys that, if given, will be the only keys used to sign the transaction.\n"
576 + HelpRequiringPassphrase() + "\n"
580 "1. \"hexstring\" (string, required) The transaction hex string\n"
581 "2. \"prevtxs\" (string, optional) An json array of previous dependent transaction outputs\n"
582 " [ (json array of json objects, or 'null' if none provided)\n"
584 " \"txid\":\"id\", (string, required) The transaction id\n"
585 " \"vout\":n, (numeric, required) The output number\n"
586 " \"scriptPubKey\": \"hex\", (string, required) script key\n"
587 " \"redeemScript\": \"hex\" (string, required for P2SH) redeem script\n"
591 "3. \"privatekeys\" (string, optional) A json array of base58-encoded private keys for signing\n"
592 " [ (json array of strings, or 'null' if none provided)\n"
593 " \"privatekey\" (string) private key in base58-encoding\n"
596 "4. \"sighashtype\" (string, optional, default=ALL) The signature hash type. Must be one of\n"
600 " \"ALL|ANYONECANPAY\"\n"
601 " \"NONE|ANYONECANPAY\"\n"
602 " \"SINGLE|ANYONECANPAY\"\n"
606 " \"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n"
607 " \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n"
608 " \"errors\" : [ (json array of objects) Script verification errors (if there are any)\n"
610 " \"txid\" : \"hash\", (string) The hash of the referenced, previous transaction\n"
611 " \"vout\" : n, (numeric) The index of the output to spent and used as input\n"
612 " \"scriptSig\" : \"hex\", (string) The hex-encoded signature script\n"
613 " \"sequence\" : n, (numeric) Script sequence number\n"
614 " \"error\" : \"text\" (string) Verification or signing error related to the input\n"
621 + HelpExampleCli("signrawtransaction", "\"myhex\"")
622 + HelpExampleRpc("signrawtransaction", "\"myhex\"")
626 LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
630 RPCTypeCheck(params, boost::assign::list_of(str_type)(array_type)(array_type)(str_type), true);
632 vector<unsigned char> txData(ParseHexV(params[0], "argument 1"));
633 CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
634 vector<CMutableTransaction> txVariants;
635 while (!ssData.empty()) {
637 CMutableTransaction tx;
639 txVariants.push_back(tx);
641 catch (const std::exception&) {
642 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
646 if (txVariants.empty())
647 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transaction");
649 // mergedTx will end up with all the signatures; it
650 // starts as a clone of the rawtx:
651 CMutableTransaction mergedTx(txVariants[0]);
653 // Fetch previous transactions (inputs):
654 CCoinsView viewDummy;
655 CCoinsViewCache view(&viewDummy);
658 CCoinsViewCache &viewChain = *pcoinsTip;
659 CCoinsViewMemPool viewMempool(&viewChain, mempool);
660 view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
662 BOOST_FOREACH(const CTxIn& txin, mergedTx.vin) {
663 const uint256& prevHash = txin.prevout.hash;
665 view.AccessCoins(prevHash); // this is certainly allowed to fail
668 view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
671 bool fGivenKeys = false;
672 CBasicKeyStore tempKeystore;
673 if (params.size() > 2 && params[2].type() != null_type) {
675 Array keys = params[2].get_array();
676 BOOST_FOREACH(Value k, keys) {
677 CBitcoinSecret vchSecret;
678 bool fGood = vchSecret.SetString(k.get_str());
680 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
681 CKey key = vchSecret.GetKey();
683 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
684 tempKeystore.AddKey(key);
688 else if (pwalletMain)
689 EnsureWalletIsUnlocked();
692 // Add previous txouts given in the RPC call:
693 if (params.size() > 1 && params[1].type() != null_type) {
694 Array prevTxs = params[1].get_array();
695 BOOST_FOREACH(Value& p, prevTxs) {
696 if (p.type() != obj_type)
697 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}");
699 Object prevOut = p.get_obj();
701 RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type));
703 uint256 txid = ParseHashO(prevOut, "txid");
705 int nOut = find_value(prevOut, "vout").get_int();
707 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout must be positive");
709 vector<unsigned char> pkData(ParseHexO(prevOut, "scriptPubKey"));
710 CScript scriptPubKey(pkData.begin(), pkData.end());
713 CCoinsModifier coins = view.ModifyCoins(txid);
714 if (coins->IsAvailable(nOut) && coins->vout[nOut].scriptPubKey != scriptPubKey) {
715 string err("Previous output scriptPubKey mismatch:\n");
716 err = err + coins->vout[nOut].scriptPubKey.ToString() + "\nvs:\n"+
717 scriptPubKey.ToString();
718 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err);
720 if ((unsigned int)nOut >= coins->vout.size())
721 coins->vout.resize(nOut+1);
722 coins->vout[nOut].scriptPubKey = scriptPubKey;
723 coins->vout[nOut].nValue = 0; // we don't know the actual output value
726 // if redeemScript given and not using the local wallet (private keys
727 // given), add redeemScript to the tempKeystore so it can be signed:
728 if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) {
729 RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)("redeemScript",str_type));
730 Value v = find_value(prevOut, "redeemScript");
731 if (!(v == Value::null)) {
732 vector<unsigned char> rsData(ParseHexV(v, "redeemScript"));
733 CScript redeemScript(rsData.begin(), rsData.end());
734 tempKeystore.AddCScript(redeemScript);
741 const CKeyStore& keystore = ((fGivenKeys || !pwalletMain) ? tempKeystore : *pwalletMain);
743 const CKeyStore& keystore = tempKeystore;
746 int nHashType = SIGHASH_ALL;
747 if (params.size() > 3 && params[3].type() != null_type) {
748 static map<string, int> mapSigHashValues =
749 boost::assign::map_list_of
750 (string("ALL"), int(SIGHASH_ALL))
751 (string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY))
752 (string("NONE"), int(SIGHASH_NONE))
753 (string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY))
754 (string("SINGLE"), int(SIGHASH_SINGLE))
755 (string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY))
757 string strHashType = params[3].get_str();
758 if (mapSigHashValues.count(strHashType))
759 nHashType = mapSigHashValues[strHashType];
761 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param");
764 bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
766 // Script verification errors
770 for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
771 CTxIn& txin = mergedTx.vin[i];
772 const CCoins* coins = view.AccessCoins(txin.prevout.hash);
773 if (coins == NULL || !coins->IsAvailable(txin.prevout.n)) {
774 TxInErrorToJSON(txin, vErrors, "Input not found or already spent");
777 const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey;
779 txin.scriptSig.clear();
780 // Only sign SIGHASH_SINGLE if there's a corresponding output:
781 if (!fHashSingle || (i < mergedTx.vout.size()))
782 SignSignature(keystore, prevPubKey, mergedTx, i, nHashType);
784 // ... and merge in other signatures:
785 BOOST_FOREACH(const CMutableTransaction& txv, txVariants) {
786 txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig);
788 ScriptError serror = SCRIPT_ERR_OK;
789 if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i), &serror)) {
790 TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror));
793 bool fComplete = vErrors.empty();
796 result.push_back(Pair("hex", EncodeHexTx(mergedTx)));
797 result.push_back(Pair("complete", fComplete));
798 if (!vErrors.empty()) {
799 result.push_back(Pair("errors", vErrors));
805 Value sendrawtransaction(const Array& params, bool fHelp)
807 if (fHelp || params.size() < 1 || params.size() > 2)
809 "sendrawtransaction \"hexstring\" ( allowhighfees )\n"
810 "\nSubmits raw transaction (serialized, hex-encoded) to local node and network.\n"
811 "\nAlso see createrawtransaction and signrawtransaction calls.\n"
813 "1. \"hexstring\" (string, required) The hex string of the raw transaction)\n"
814 "2. allowhighfees (boolean, optional, default=false) Allow high fees\n"
816 "\"hex\" (string) The transaction hash in hex\n"
818 "\nCreate a transaction\n"
819 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") +
820 "Sign the transaction, and get back the hex\n"
821 + HelpExampleCli("signrawtransaction", "\"myhex\"") +
822 "\nSend the transaction (signed hex)\n"
823 + HelpExampleCli("sendrawtransaction", "\"signedhex\"") +
824 "\nAs a json rpc call\n"
825 + HelpExampleRpc("sendrawtransaction", "\"signedhex\"")
829 RPCTypeCheck(params, boost::assign::list_of(str_type)(bool_type));
831 // parse hex string from parameter
833 if (!DecodeHexTx(tx, params[0].get_str()))
834 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
835 uint256 hashTx = tx.GetHash();
837 bool fOverrideFees = false;
838 if (params.size() > 1)
839 fOverrideFees = params[1].get_bool();
841 CCoinsViewCache &view = *pcoinsTip;
842 const CCoins* existingCoins = view.AccessCoins(hashTx);
843 bool fHaveMempool = mempool.exists(hashTx);
844 bool fHaveChain = existingCoins && existingCoins->nHeight < 1000000000;
845 if (!fHaveMempool && !fHaveChain) {
846 // push to local node and sync with wallets
847 CValidationState state;
849 if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees)) {
850 if (state.IsInvalid()) {
851 throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
853 if (fMissingInputs) {
854 throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs");
856 throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason());
859 } else if (fHaveChain) {
860 throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain");
862 RelayTransaction(tx);
864 return hashTx.GetHex();