Add UpdatedBlockTip signal to CMainSignals and CValidationInterface
[bitcoinplatinum.git] / src / rpcrawtransaction.cpp
blob9eeca5b7d922d03f3c43f219c8f9f0d894530288
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 "base58.h"
7 #include "chain.h"
8 #include "coins.h"
9 #include "consensus/validation.h"
10 #include "core_io.h"
11 #include "init.h"
12 #include "keystore.h"
13 #include "main.h"
14 #include "merkleblock.h"
15 #include "net.h"
16 #include "policy/policy.h"
17 #include "primitives/transaction.h"
18 #include "rpcserver.h"
19 #include "script/script.h"
20 #include "script/script_error.h"
21 #include "script/sign.h"
22 #include "script/standard.h"
23 #include "txmempool.h"
24 #include "uint256.h"
25 #include "utilstrencodings.h"
26 #ifdef ENABLE_WALLET
27 #include "wallet/wallet.h"
28 #endif
30 #include <stdint.h>
32 #include <boost/assign/list_of.hpp>
34 #include "univalue/univalue.h"
36 using namespace std;
38 void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex)
40 txnouttype type;
41 vector<CTxDestination> addresses;
42 int nRequired;
44 out.push_back(Pair("asm", scriptPubKey.ToString()));
45 if (fIncludeHex)
46 out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
48 if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) {
49 out.push_back(Pair("type", GetTxnOutputType(type)));
50 return;
53 out.push_back(Pair("reqSigs", nRequired));
54 out.push_back(Pair("type", GetTxnOutputType(type)));
56 UniValue a(UniValue::VARR);
57 BOOST_FOREACH(const CTxDestination& addr, addresses)
58 a.push_back(CBitcoinAddress(addr).ToString());
59 out.push_back(Pair("addresses", a));
62 void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
64 entry.push_back(Pair("txid", tx.GetHash().GetHex()));
65 entry.push_back(Pair("version", tx.nVersion));
66 entry.push_back(Pair("locktime", (int64_t)tx.nLockTime));
67 UniValue vin(UniValue::VARR);
68 BOOST_FOREACH(const CTxIn& txin, tx.vin) {
69 UniValue in(UniValue::VOBJ);
70 if (tx.IsCoinBase())
71 in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
72 else {
73 in.push_back(Pair("txid", txin.prevout.hash.GetHex()));
74 in.push_back(Pair("vout", (int64_t)txin.prevout.n));
75 UniValue o(UniValue::VOBJ);
76 o.push_back(Pair("asm", txin.scriptSig.ToString()));
77 o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
78 in.push_back(Pair("scriptSig", o));
80 in.push_back(Pair("sequence", (int64_t)txin.nSequence));
81 vin.push_back(in);
83 entry.push_back(Pair("vin", vin));
84 UniValue vout(UniValue::VARR);
85 for (unsigned int i = 0; i < tx.vout.size(); i++) {
86 const CTxOut& txout = tx.vout[i];
87 UniValue out(UniValue::VOBJ);
88 out.push_back(Pair("value", ValueFromAmount(txout.nValue)));
89 out.push_back(Pair("n", (int64_t)i));
90 UniValue o(UniValue::VOBJ);
91 ScriptPubKeyToJSON(txout.scriptPubKey, o, true);
92 out.push_back(Pair("scriptPubKey", o));
93 vout.push_back(out);
95 entry.push_back(Pair("vout", vout));
97 if (!hashBlock.IsNull()) {
98 entry.push_back(Pair("blockhash", hashBlock.GetHex()));
99 BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
100 if (mi != mapBlockIndex.end() && (*mi).second) {
101 CBlockIndex* pindex = (*mi).second;
102 if (chainActive.Contains(pindex)) {
103 entry.push_back(Pair("confirmations", 1 + chainActive.Height() - pindex->nHeight));
104 entry.push_back(Pair("time", pindex->GetBlockTime()));
105 entry.push_back(Pair("blocktime", pindex->GetBlockTime()));
107 else
108 entry.push_back(Pair("confirmations", 0));
113 UniValue getrawtransaction(const UniValue& params, bool fHelp)
115 if (fHelp || params.size() < 1 || params.size() > 2)
116 throw runtime_error(
117 "getrawtransaction \"txid\" ( verbose )\n"
118 "\nNOTE: By default this function only works sometimes. This is when the tx is in the mempool\n"
119 "or there is an unspent output in the utxo for this transaction. To make it always work,\n"
120 "you need to maintain a transaction index, using the -txindex command line option.\n"
121 "\nReturn the raw transaction data.\n"
122 "\nIf verbose=0, returns a string that is serialized, hex-encoded data for 'txid'.\n"
123 "If verbose is non-zero, returns an Object with information about 'txid'.\n"
125 "\nArguments:\n"
126 "1. \"txid\" (string, required) The transaction id\n"
127 "2. verbose (numeric, optional, default=0) If 0, return a string, other return a json object\n"
129 "\nResult (if verbose is not set or set to 0):\n"
130 "\"data\" (string) The serialized, hex-encoded data for 'txid'\n"
132 "\nResult (if verbose > 0):\n"
133 "{\n"
134 " \"hex\" : \"data\", (string) The serialized, hex-encoded data for 'txid'\n"
135 " \"txid\" : \"id\", (string) The transaction id (same as provided)\n"
136 " \"version\" : n, (numeric) The version\n"
137 " \"locktime\" : ttt, (numeric) The lock time\n"
138 " \"vin\" : [ (array of json objects)\n"
139 " {\n"
140 " \"txid\": \"id\", (string) The transaction id\n"
141 " \"vout\": n, (numeric) \n"
142 " \"scriptSig\": { (json object) The script\n"
143 " \"asm\": \"asm\", (string) asm\n"
144 " \"hex\": \"hex\" (string) hex\n"
145 " },\n"
146 " \"sequence\": n (numeric) The script sequence number\n"
147 " }\n"
148 " ,...\n"
149 " ],\n"
150 " \"vout\" : [ (array of json objects)\n"
151 " {\n"
152 " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n"
153 " \"n\" : n, (numeric) index\n"
154 " \"scriptPubKey\" : { (json object)\n"
155 " \"asm\" : \"asm\", (string) the asm\n"
156 " \"hex\" : \"hex\", (string) the hex\n"
157 " \"reqSigs\" : n, (numeric) The required sigs\n"
158 " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
159 " \"addresses\" : [ (json array of string)\n"
160 " \"bitcoinaddress\" (string) bitcoin address\n"
161 " ,...\n"
162 " ]\n"
163 " }\n"
164 " }\n"
165 " ,...\n"
166 " ],\n"
167 " \"blockhash\" : \"hash\", (string) the block hash\n"
168 " \"confirmations\" : n, (numeric) The confirmations\n"
169 " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT)\n"
170 " \"blocktime\" : ttt (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
171 "}\n"
173 "\nExamples:\n"
174 + HelpExampleCli("getrawtransaction", "\"mytxid\"")
175 + HelpExampleCli("getrawtransaction", "\"mytxid\" 1")
176 + HelpExampleRpc("getrawtransaction", "\"mytxid\", 1")
179 LOCK(cs_main);
181 uint256 hash = ParseHashV(params[0], "parameter 1");
183 bool fVerbose = false;
184 if (params.size() > 1)
185 fVerbose = (params[1].get_int() != 0);
187 CTransaction tx;
188 uint256 hashBlock;
189 if (!GetTransaction(hash, tx, hashBlock, true))
190 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction");
192 string strHex = EncodeHexTx(tx);
194 if (!fVerbose)
195 return strHex;
197 UniValue result(UniValue::VOBJ);
198 result.push_back(Pair("hex", strHex));
199 TxToJSON(tx, hashBlock, result);
200 return result;
203 UniValue gettxoutproof(const UniValue& params, bool fHelp)
205 if (fHelp || (params.size() != 1 && params.size() != 2))
206 throw runtime_error(
207 "gettxoutproof [\"txid\",...] ( blockhash )\n"
208 "\nReturns a hex-encoded proof that \"txid\" was included in a block.\n"
209 "\nNOTE: By default this function only works sometimes. This is when there is an\n"
210 "unspent output in the utxo for this transaction. To make it always work,\n"
211 "you need to maintain a transaction index, using the -txindex command line option or\n"
212 "specify the block in which the transaction is included in manually (by blockhash).\n"
213 "\nReturn the raw transaction data.\n"
214 "\nArguments:\n"
215 "1. \"txids\" (string) A json array of txids to filter\n"
216 " [\n"
217 " \"txid\" (string) A transaction hash\n"
218 " ,...\n"
219 " ]\n"
220 "2. \"block hash\" (string, optional) If specified, looks for txid in the block with this hash\n"
221 "\nResult:\n"
222 "\"data\" (string) A string that is a serialized, hex-encoded data for the proof.\n"
225 set<uint256> setTxids;
226 uint256 oneTxid;
227 UniValue txids = params[0].get_array();
228 for (unsigned int idx = 0; idx < txids.size(); idx++) {
229 const UniValue& txid = txids[idx];
230 if (txid.get_str().length() != 64 || !IsHex(txid.get_str()))
231 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid txid ")+txid.get_str());
232 uint256 hash(uint256S(txid.get_str()));
233 if (setTxids.count(hash))
234 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated txid: ")+txid.get_str());
235 setTxids.insert(hash);
236 oneTxid = hash;
239 LOCK(cs_main);
241 CBlockIndex* pblockindex = NULL;
243 uint256 hashBlock;
244 if (params.size() > 1)
246 hashBlock = uint256S(params[1].get_str());
247 if (!mapBlockIndex.count(hashBlock))
248 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
249 pblockindex = mapBlockIndex[hashBlock];
250 } else {
251 CCoins coins;
252 if (pcoinsTip->GetCoins(oneTxid, coins) && coins.nHeight > 0 && coins.nHeight <= chainActive.Height())
253 pblockindex = chainActive[coins.nHeight];
256 if (pblockindex == NULL)
258 CTransaction tx;
259 if (!GetTransaction(oneTxid, tx, hashBlock, false) || hashBlock.IsNull())
260 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block");
261 if (!mapBlockIndex.count(hashBlock))
262 throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt");
263 pblockindex = mapBlockIndex[hashBlock];
266 CBlock block;
267 if(!ReadBlockFromDisk(block, pblockindex))
268 throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
270 unsigned int ntxFound = 0;
271 BOOST_FOREACH(const CTransaction&tx, block.vtx)
272 if (setTxids.count(tx.GetHash()))
273 ntxFound++;
274 if (ntxFound != setTxids.size())
275 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "(Not all) transactions not found in specified block");
277 CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION);
278 CMerkleBlock mb(block, setTxids);
279 ssMB << mb;
280 std::string strHex = HexStr(ssMB.begin(), ssMB.end());
281 return strHex;
284 UniValue verifytxoutproof(const UniValue& params, bool fHelp)
286 if (fHelp || params.size() != 1)
287 throw runtime_error(
288 "verifytxoutproof \"proof\"\n"
289 "\nVerifies that a proof points to a transaction in a block, returning the transaction it commits to\n"
290 "and throwing an RPC error if the block is not in our best chain\n"
291 "\nArguments:\n"
292 "1. \"proof\" (string, required) The hex-encoded proof generated by gettxoutproof\n"
293 "\nResult:\n"
294 "[\"txid\"] (array, strings) The txid(s) which the proof commits to, or empty array if the proof is invalid\n"
297 CDataStream ssMB(ParseHexV(params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION);
298 CMerkleBlock merkleBlock;
299 ssMB >> merkleBlock;
301 UniValue res(UniValue::VARR);
303 vector<uint256> vMatch;
304 if (merkleBlock.txn.ExtractMatches(vMatch) != merkleBlock.header.hashMerkleRoot)
305 return res;
307 LOCK(cs_main);
309 if (!mapBlockIndex.count(merkleBlock.header.GetHash()) || !chainActive.Contains(mapBlockIndex[merkleBlock.header.GetHash()]))
310 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain");
312 BOOST_FOREACH(const uint256& hash, vMatch)
313 res.push_back(hash.GetHex());
314 return res;
317 UniValue createrawtransaction(const UniValue& params, bool fHelp)
319 if (fHelp || params.size() != 2)
320 throw runtime_error(
321 "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,\"data\":\"hex\",...}\n"
322 "\nCreate a transaction spending the given inputs and creating new outputs.\n"
323 "Outputs can be addresses or data.\n"
324 "Returns hex-encoded raw transaction.\n"
325 "Note that the transaction's inputs are not signed, and\n"
326 "it is not stored in the wallet or transmitted to the network.\n"
328 "\nArguments:\n"
329 "1. \"transactions\" (string, required) A json array of json objects\n"
330 " [\n"
331 " {\n"
332 " \"txid\":\"id\", (string, required) The transaction id\n"
333 " \"vout\":n (numeric, required) The output number\n"
334 " }\n"
335 " ,...\n"
336 " ]\n"
337 "2. \"outputs\" (string, required) a json object with outputs\n"
338 " {\n"
339 " \"address\": x.xxx (numeric, required) The key is the bitcoin address, the value is the " + CURRENCY_UNIT + " amount\n"
340 " \"data\": \"hex\", (string, required) The key is \"data\", the value is hex encoded data\n"
341 " ...\n"
342 " }\n"
343 "\nResult:\n"
344 "\"transaction\" (string) hex string of the transaction\n"
346 "\nExamples\n"
347 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":0.01}\"")
348 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"data\\\":\\\"00010203\\\"}\"")
349 + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\"")
350 + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"data\\\":\\\"00010203\\\"}\"")
353 LOCK(cs_main);
354 RPCTypeCheck(params, boost::assign::list_of(UniValue::VARR)(UniValue::VOBJ));
356 UniValue inputs = params[0].get_array();
357 UniValue sendTo = params[1].get_obj();
359 CMutableTransaction rawTx;
361 for (unsigned int idx = 0; idx < inputs.size(); idx++) {
362 const UniValue& input = inputs[idx];
363 const UniValue& o = input.get_obj();
365 uint256 txid = ParseHashO(o, "txid");
367 const UniValue& vout_v = find_value(o, "vout");
368 if (!vout_v.isNum())
369 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");
370 int nOutput = vout_v.get_int();
371 if (nOutput < 0)
372 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
374 CTxIn in(COutPoint(txid, nOutput));
375 rawTx.vin.push_back(in);
378 set<CBitcoinAddress> setAddress;
379 vector<string> addrList = sendTo.getKeys();
380 BOOST_FOREACH(const string& name_, addrList) {
382 if (name_ == "data") {
383 std::vector<unsigned char> data = ParseHexV(sendTo[name_].getValStr(),"Data");
385 CTxOut out(0, CScript() << OP_RETURN << data);
386 rawTx.vout.push_back(out);
387 } else {
388 CBitcoinAddress address(name_);
389 if (!address.IsValid())
390 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+name_);
392 if (setAddress.count(address))
393 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+name_);
394 setAddress.insert(address);
396 CScript scriptPubKey = GetScriptForDestination(address.Get());
397 CAmount nAmount = AmountFromValue(sendTo[name_]);
399 CTxOut out(nAmount, scriptPubKey);
400 rawTx.vout.push_back(out);
404 return EncodeHexTx(rawTx);
407 UniValue decoderawtransaction(const UniValue& params, bool fHelp)
409 if (fHelp || params.size() != 1)
410 throw runtime_error(
411 "decoderawtransaction \"hexstring\"\n"
412 "\nReturn a JSON object representing the serialized, hex-encoded transaction.\n"
414 "\nArguments:\n"
415 "1. \"hex\" (string, required) The transaction hex string\n"
417 "\nResult:\n"
418 "{\n"
419 " \"txid\" : \"id\", (string) The transaction id\n"
420 " \"version\" : n, (numeric) The version\n"
421 " \"locktime\" : ttt, (numeric) The lock time\n"
422 " \"vin\" : [ (array of json objects)\n"
423 " {\n"
424 " \"txid\": \"id\", (string) The transaction id\n"
425 " \"vout\": n, (numeric) The output number\n"
426 " \"scriptSig\": { (json object) The script\n"
427 " \"asm\": \"asm\", (string) asm\n"
428 " \"hex\": \"hex\" (string) hex\n"
429 " },\n"
430 " \"sequence\": n (numeric) The script sequence number\n"
431 " }\n"
432 " ,...\n"
433 " ],\n"
434 " \"vout\" : [ (array of json objects)\n"
435 " {\n"
436 " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n"
437 " \"n\" : n, (numeric) index\n"
438 " \"scriptPubKey\" : { (json object)\n"
439 " \"asm\" : \"asm\", (string) the asm\n"
440 " \"hex\" : \"hex\", (string) the hex\n"
441 " \"reqSigs\" : n, (numeric) The required sigs\n"
442 " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
443 " \"addresses\" : [ (json array of string)\n"
444 " \"12tvKAXCxZjSmdNbao16dKXC8tRWfcF5oc\" (string) bitcoin address\n"
445 " ,...\n"
446 " ]\n"
447 " }\n"
448 " }\n"
449 " ,...\n"
450 " ],\n"
451 "}\n"
453 "\nExamples:\n"
454 + HelpExampleCli("decoderawtransaction", "\"hexstring\"")
455 + HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
458 LOCK(cs_main);
459 RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR));
461 CTransaction tx;
463 if (!DecodeHexTx(tx, params[0].get_str()))
464 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
466 UniValue result(UniValue::VOBJ);
467 TxToJSON(tx, uint256(), result);
469 return result;
472 UniValue decodescript(const UniValue& params, bool fHelp)
474 if (fHelp || params.size() != 1)
475 throw runtime_error(
476 "decodescript \"hex\"\n"
477 "\nDecode a hex-encoded script.\n"
478 "\nArguments:\n"
479 "1. \"hex\" (string) the hex encoded script\n"
480 "\nResult:\n"
481 "{\n"
482 " \"asm\":\"asm\", (string) Script public key\n"
483 " \"hex\":\"hex\", (string) hex encoded public key\n"
484 " \"type\":\"type\", (string) The output type\n"
485 " \"reqSigs\": n, (numeric) The required signatures\n"
486 " \"addresses\": [ (json array of string)\n"
487 " \"address\" (string) bitcoin address\n"
488 " ,...\n"
489 " ],\n"
490 " \"p2sh\",\"address\" (string) script address\n"
491 "}\n"
492 "\nExamples:\n"
493 + HelpExampleCli("decodescript", "\"hexstring\"")
494 + HelpExampleRpc("decodescript", "\"hexstring\"")
497 LOCK(cs_main);
498 RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR));
500 UniValue r(UniValue::VOBJ);
501 CScript script;
502 if (params[0].get_str().size() > 0){
503 vector<unsigned char> scriptData(ParseHexV(params[0], "argument"));
504 script = CScript(scriptData.begin(), scriptData.end());
505 } else {
506 // Empty scripts are valid
508 ScriptPubKeyToJSON(script, r, false);
510 r.push_back(Pair("p2sh", CBitcoinAddress(CScriptID(script)).ToString()));
511 return r;
514 /** Pushes a JSON object for script verification or signing errors to vErrorsRet. */
515 static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std::string& strMessage)
517 UniValue entry(UniValue::VOBJ);
518 entry.push_back(Pair("txid", txin.prevout.hash.ToString()));
519 entry.push_back(Pair("vout", (uint64_t)txin.prevout.n));
520 entry.push_back(Pair("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
521 entry.push_back(Pair("sequence", (uint64_t)txin.nSequence));
522 entry.push_back(Pair("error", strMessage));
523 vErrorsRet.push_back(entry);
526 UniValue signrawtransaction(const UniValue& params, bool fHelp)
528 if (fHelp || params.size() < 1 || params.size() > 4)
529 throw runtime_error(
530 "signrawtransaction \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] [\"privatekey1\",...] sighashtype )\n"
531 "\nSign inputs for raw transaction (serialized, hex-encoded).\n"
532 "The second optional argument (may be null) is an array of previous transaction outputs that\n"
533 "this transaction depends on but may not yet be in the block chain.\n"
534 "The third optional argument (may be null) is an array of base58-encoded private\n"
535 "keys that, if given, will be the only keys used to sign the transaction.\n"
536 #ifdef ENABLE_WALLET
537 + HelpRequiringPassphrase() + "\n"
538 #endif
540 "\nArguments:\n"
541 "1. \"hexstring\" (string, required) The transaction hex string\n"
542 "2. \"prevtxs\" (string, optional) An json array of previous dependent transaction outputs\n"
543 " [ (json array of json objects, or 'null' if none provided)\n"
544 " {\n"
545 " \"txid\":\"id\", (string, required) The transaction id\n"
546 " \"vout\":n, (numeric, required) The output number\n"
547 " \"scriptPubKey\": \"hex\", (string, required) script key\n"
548 " \"redeemScript\": \"hex\" (string, required for P2SH) redeem script\n"
549 " }\n"
550 " ,...\n"
551 " ]\n"
552 "3. \"privatekeys\" (string, optional) A json array of base58-encoded private keys for signing\n"
553 " [ (json array of strings, or 'null' if none provided)\n"
554 " \"privatekey\" (string) private key in base58-encoding\n"
555 " ,...\n"
556 " ]\n"
557 "4. \"sighashtype\" (string, optional, default=ALL) The signature hash type. Must be one of\n"
558 " \"ALL\"\n"
559 " \"NONE\"\n"
560 " \"SINGLE\"\n"
561 " \"ALL|ANYONECANPAY\"\n"
562 " \"NONE|ANYONECANPAY\"\n"
563 " \"SINGLE|ANYONECANPAY\"\n"
565 "\nResult:\n"
566 "{\n"
567 " \"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n"
568 " \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n"
569 " \"errors\" : [ (json array of objects) Script verification errors (if there are any)\n"
570 " {\n"
571 " \"txid\" : \"hash\", (string) The hash of the referenced, previous transaction\n"
572 " \"vout\" : n, (numeric) The index of the output to spent and used as input\n"
573 " \"scriptSig\" : \"hex\", (string) The hex-encoded signature script\n"
574 " \"sequence\" : n, (numeric) Script sequence number\n"
575 " \"error\" : \"text\" (string) Verification or signing error related to the input\n"
576 " }\n"
577 " ,...\n"
578 " ]\n"
579 "}\n"
581 "\nExamples:\n"
582 + HelpExampleCli("signrawtransaction", "\"myhex\"")
583 + HelpExampleRpc("signrawtransaction", "\"myhex\"")
586 #ifdef ENABLE_WALLET
587 LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
588 #else
589 LOCK(cs_main);
590 #endif
591 RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VARR)(UniValue::VARR)(UniValue::VSTR), true);
593 vector<unsigned char> txData(ParseHexV(params[0], "argument 1"));
594 CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
595 vector<CMutableTransaction> txVariants;
596 while (!ssData.empty()) {
597 try {
598 CMutableTransaction tx;
599 ssData >> tx;
600 txVariants.push_back(tx);
602 catch (const std::exception&) {
603 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
607 if (txVariants.empty())
608 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transaction");
610 // mergedTx will end up with all the signatures; it
611 // starts as a clone of the rawtx:
612 CMutableTransaction mergedTx(txVariants[0]);
614 // Fetch previous transactions (inputs):
615 CCoinsView viewDummy;
616 CCoinsViewCache view(&viewDummy);
618 LOCK(mempool.cs);
619 CCoinsViewCache &viewChain = *pcoinsTip;
620 CCoinsViewMemPool viewMempool(&viewChain, mempool);
621 view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
623 BOOST_FOREACH(const CTxIn& txin, mergedTx.vin) {
624 const uint256& prevHash = txin.prevout.hash;
625 CCoins coins;
626 view.AccessCoins(prevHash); // this is certainly allowed to fail
629 view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
632 bool fGivenKeys = false;
633 CBasicKeyStore tempKeystore;
634 if (params.size() > 2 && !params[2].isNull()) {
635 fGivenKeys = true;
636 UniValue keys = params[2].get_array();
637 for (unsigned int idx = 0; idx < keys.size(); idx++) {
638 UniValue k = keys[idx];
639 CBitcoinSecret vchSecret;
640 bool fGood = vchSecret.SetString(k.get_str());
641 if (!fGood)
642 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
643 CKey key = vchSecret.GetKey();
644 if (!key.IsValid())
645 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
646 tempKeystore.AddKey(key);
649 #ifdef ENABLE_WALLET
650 else if (pwalletMain)
651 EnsureWalletIsUnlocked();
652 #endif
654 // Add previous txouts given in the RPC call:
655 if (params.size() > 1 && !params[1].isNull()) {
656 UniValue prevTxs = params[1].get_array();
657 for (unsigned int idx = 0; idx < prevTxs.size(); idx++) {
658 const UniValue& p = prevTxs[idx];
659 if (!p.isObject())
660 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}");
662 UniValue prevOut = p.get_obj();
664 RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR));
666 uint256 txid = ParseHashO(prevOut, "txid");
668 int nOut = find_value(prevOut, "vout").get_int();
669 if (nOut < 0)
670 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout must be positive");
672 vector<unsigned char> pkData(ParseHexO(prevOut, "scriptPubKey"));
673 CScript scriptPubKey(pkData.begin(), pkData.end());
676 CCoinsModifier coins = view.ModifyCoins(txid);
677 if (coins->IsAvailable(nOut) && coins->vout[nOut].scriptPubKey != scriptPubKey) {
678 string err("Previous output scriptPubKey mismatch:\n");
679 err = err + coins->vout[nOut].scriptPubKey.ToString() + "\nvs:\n"+
680 scriptPubKey.ToString();
681 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err);
683 if ((unsigned int)nOut >= coins->vout.size())
684 coins->vout.resize(nOut+1);
685 coins->vout[nOut].scriptPubKey = scriptPubKey;
686 coins->vout[nOut].nValue = 0; // we don't know the actual output value
689 // if redeemScript given and not using the local wallet (private keys
690 // given), add redeemScript to the tempKeystore so it can be signed:
691 if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) {
692 RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR)("redeemScript",UniValue::VSTR));
693 UniValue v = find_value(prevOut, "redeemScript");
694 if (!v.isNull()) {
695 vector<unsigned char> rsData(ParseHexV(v, "redeemScript"));
696 CScript redeemScript(rsData.begin(), rsData.end());
697 tempKeystore.AddCScript(redeemScript);
703 #ifdef ENABLE_WALLET
704 const CKeyStore& keystore = ((fGivenKeys || !pwalletMain) ? tempKeystore : *pwalletMain);
705 #else
706 const CKeyStore& keystore = tempKeystore;
707 #endif
709 int nHashType = SIGHASH_ALL;
710 if (params.size() > 3 && !params[3].isNull()) {
711 static map<string, int> mapSigHashValues =
712 boost::assign::map_list_of
713 (string("ALL"), int(SIGHASH_ALL))
714 (string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY))
715 (string("NONE"), int(SIGHASH_NONE))
716 (string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY))
717 (string("SINGLE"), int(SIGHASH_SINGLE))
718 (string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY))
720 string strHashType = params[3].get_str();
721 if (mapSigHashValues.count(strHashType))
722 nHashType = mapSigHashValues[strHashType];
723 else
724 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param");
727 bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
729 // Script verification errors
730 UniValue vErrors(UniValue::VARR);
732 // Sign what we can:
733 for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
734 CTxIn& txin = mergedTx.vin[i];
735 const CCoins* coins = view.AccessCoins(txin.prevout.hash);
736 if (coins == NULL || !coins->IsAvailable(txin.prevout.n)) {
737 TxInErrorToJSON(txin, vErrors, "Input not found or already spent");
738 continue;
740 const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey;
742 txin.scriptSig.clear();
743 // Only sign SIGHASH_SINGLE if there's a corresponding output:
744 if (!fHashSingle || (i < mergedTx.vout.size()))
745 SignSignature(keystore, prevPubKey, mergedTx, i, nHashType);
747 // ... and merge in other signatures:
748 BOOST_FOREACH(const CMutableTransaction& txv, txVariants) {
749 txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig);
751 ScriptError serror = SCRIPT_ERR_OK;
752 if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i), &serror)) {
753 TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror));
756 bool fComplete = vErrors.empty();
758 UniValue result(UniValue::VOBJ);
759 result.push_back(Pair("hex", EncodeHexTx(mergedTx)));
760 result.push_back(Pair("complete", fComplete));
761 if (!vErrors.empty()) {
762 result.push_back(Pair("errors", vErrors));
765 return result;
768 UniValue sendrawtransaction(const UniValue& params, bool fHelp)
770 if (fHelp || params.size() < 1 || params.size() > 2)
771 throw runtime_error(
772 "sendrawtransaction \"hexstring\" ( allowhighfees )\n"
773 "\nSubmits raw transaction (serialized, hex-encoded) to local node and network.\n"
774 "\nAlso see createrawtransaction and signrawtransaction calls.\n"
775 "\nArguments:\n"
776 "1. \"hexstring\" (string, required) The hex string of the raw transaction)\n"
777 "2. allowhighfees (boolean, optional, default=false) Allow high fees\n"
778 "\nResult:\n"
779 "\"hex\" (string) The transaction hash in hex\n"
780 "\nExamples:\n"
781 "\nCreate a transaction\n"
782 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") +
783 "Sign the transaction, and get back the hex\n"
784 + HelpExampleCli("signrawtransaction", "\"myhex\"") +
785 "\nSend the transaction (signed hex)\n"
786 + HelpExampleCli("sendrawtransaction", "\"signedhex\"") +
787 "\nAs a json rpc call\n"
788 + HelpExampleRpc("sendrawtransaction", "\"signedhex\"")
791 LOCK(cs_main);
792 RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VBOOL));
794 // parse hex string from parameter
795 CTransaction tx;
796 if (!DecodeHexTx(tx, params[0].get_str()))
797 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
798 uint256 hashTx = tx.GetHash();
800 bool fOverrideFees = false;
801 if (params.size() > 1)
802 fOverrideFees = params[1].get_bool();
804 CCoinsViewCache &view = *pcoinsTip;
805 const CCoins* existingCoins = view.AccessCoins(hashTx);
806 bool fHaveMempool = mempool.exists(hashTx);
807 bool fHaveChain = existingCoins && existingCoins->nHeight < 1000000000;
808 if (!fHaveMempool && !fHaveChain) {
809 // push to local node and sync with wallets
810 CValidationState state;
811 bool fMissingInputs;
812 if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees)) {
813 if (state.IsInvalid()) {
814 throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
815 } else {
816 if (fMissingInputs) {
817 throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs");
819 throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason());
822 } else if (fHaveChain) {
823 throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain");
825 RelayTransaction(tx);
827 return hashTx.GetHex();