]> Git Repo - VerusCoin.git/blame - src/rpcrawtransaction.cpp
Auto merge of #1980 - bitcartel:fix_z_sendmany_logging_bug_txid, r=ebfull
[VerusCoin.git] / src / rpcrawtransaction.cpp
CommitLineData
a2709fad 1// Copyright (c) 2010 Satoshi Nakamoto
8ac2a4e1 2// Copyright (c) 2009-2015 The Bitcoin Core developers
72fb3d29 3// Distributed under the MIT software license, see the accompanying
a2709fad
GA
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
a2709fad 6#include "base58.h"
da29ecbc 7#include "consensus/validation.h"
ae775b5b 8#include "core_io.h"
a2709fad 9#include "init.h"
c037531d
PK
10#include "keystore.h"
11#include "main.h"
59ed61b3 12#include "merkleblock.h"
771ffb5e 13#include "net.h"
da29ecbc 14#include "primitives/transaction.h"
c037531d 15#include "rpcserver.h"
c4408a6c 16#include "script/script.h"
8ac2a4e1 17#include "script/script_error.h"
e088d65a 18#include "script/sign.h"
611116d4 19#include "script/standard.h"
51ed9ec9 20#include "uint256.h"
48ba56cd 21#ifdef ENABLE_WALLET
50c72f23 22#include "wallet/wallet.h"
48ba56cd 23#endif
a2709fad 24
51ed9ec9
BD
25#include <stdint.h>
26
27#include <boost/assign/list_of.hpp>
28#include "json/json_spirit_utils.h"
29#include "json/json_spirit_value.h"
30
a2709fad 31using namespace json_spirit;
611116d4 32using namespace std;
a2709fad 33
be066fad 34void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex)
a2709fad
GA
35{
36 txnouttype type;
37 vector<CTxDestination> addresses;
38 int nRequired;
39
40 out.push_back(Pair("asm", scriptPubKey.ToString()));
be066fad
PT
41 if (fIncludeHex)
42 out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
a2709fad 43
3ce7e669 44 if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) {
22de68df 45 out.push_back(Pair("type", GetTxnOutputType(type)));
a2709fad
GA
46 return;
47 }
48
49 out.push_back(Pair("reqSigs", nRequired));
50 out.push_back(Pair("type", GetTxnOutputType(type)));
51
52 Array a;
53 BOOST_FOREACH(const CTxDestination& addr, addresses)
54 a.push_back(CBitcoinAddress(addr).ToString());
55 out.push_back(Pair("addresses", a));
56}
57
a2709fad 58
f7cfb52d 59Array TxJoinSplitToJSON(const CTransaction& tx) {
8675d94b
SB
60 Array vjoinsplit;
61 for (unsigned int i = 0; i < tx.vjoinsplit.size(); i++) {
b7e4abd6
SB
62 const JSDescription& jsdescription = tx.vjoinsplit[i];
63 Object joinsplit;
63ea9b75 64
b7e4abd6 65 joinsplit.push_back(Pair("anchor", jsdescription.anchor.GetHex()));
63ea9b75
SB
66
67 {
bfeaf004 68 Array nullifiers;
22de1602
SB
69 BOOST_FOREACH(const uint256 nf, jsdescription.nullifiers) {
70 nullifiers.push_back(nf.GetHex());
63ea9b75 71 }
b7e4abd6 72 joinsplit.push_back(Pair("nullifiers", nullifiers));
63ea9b75
SB
73 }
74
75 {
76 Array commitments;
b7e4abd6 77 BOOST_FOREACH(const uint256 commitment, jsdescription.commitments) {
63ea9b75
SB
78 commitments.push_back(commitment.GetHex());
79 }
b7e4abd6 80 joinsplit.push_back(Pair("commitments", commitments));
63ea9b75
SB
81 }
82
83 {
84 Array macs;
b7e4abd6 85 BOOST_FOREACH(const uint256 mac, jsdescription.macs) {
63ea9b75
SB
86 macs.push_back(mac.GetHex());
87 }
b7e4abd6 88 joinsplit.push_back(Pair("macs", macs));
63ea9b75
SB
89 }
90
b7e4abd6
SB
91 joinsplit.push_back(Pair("vpub_old", ValueFromAmount(jsdescription.vpub_old)));
92 joinsplit.push_back(Pair("vpub_new", ValueFromAmount(jsdescription.vpub_new)));
63ea9b75 93
b7e4abd6 94 vjoinsplit.push_back(joinsplit);
63ea9b75 95 }
f7cfb52d
S
96 return vjoinsplit;
97}
98
99void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry)
100{
101 entry.push_back(Pair("txid", tx.GetHash().GetHex()));
102 entry.push_back(Pair("version", tx.nVersion));
103 entry.push_back(Pair("locktime", (int64_t)tx.nLockTime));
104 Array vin;
105 BOOST_FOREACH(const CTxIn& txin, tx.vin) {
106 Object in;
107 if (tx.IsCoinBase())
108 in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
109 else {
110 in.push_back(Pair("txid", txin.prevout.hash.GetHex()));
111 in.push_back(Pair("vout", (int64_t)txin.prevout.n));
112 Object o;
113 o.push_back(Pair("asm", txin.scriptSig.ToString()));
114 o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
115 in.push_back(Pair("scriptSig", o));
116 }
117 in.push_back(Pair("sequence", (int64_t)txin.nSequence));
118 vin.push_back(in);
119 }
120 entry.push_back(Pair("vin", vin));
121 Array vout;
122 for (unsigned int i = 0; i < tx.vout.size(); i++) {
123 const CTxOut& txout = tx.vout[i];
124 Object out;
125 out.push_back(Pair("value", ValueFromAmount(txout.nValue)));
126 out.push_back(Pair("n", (int64_t)i));
127 Object o;
128 ScriptPubKeyToJSON(txout.scriptPubKey, o, true);
129 out.push_back(Pair("scriptPubKey", o));
130 vout.push_back(out);
131 }
132 entry.push_back(Pair("vout", vout));
63ea9b75 133
f7cfb52d 134 Array vjoinsplit = TxJoinSplitToJSON(tx);
8675d94b 135 entry.push_back(Pair("vjoinsplit", vjoinsplit));
63ea9b75 136
4f152496 137 if (!hashBlock.IsNull()) {
a2709fad 138 entry.push_back(Pair("blockhash", hashBlock.GetHex()));
145d5be8 139 BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
3ce7e669 140 if (mi != mapBlockIndex.end() && (*mi).second) {
a2709fad 141 CBlockIndex* pindex = (*mi).second;
3ce7e669 142 if (chainActive.Contains(pindex)) {
4c6d41b8 143 entry.push_back(Pair("confirmations", 1 + chainActive.Height() - pindex->nHeight));
209377a7 144 entry.push_back(Pair("time", pindex->GetBlockTime()));
145 entry.push_back(Pair("blocktime", pindex->GetBlockTime()));
a2709fad
GA
146 }
147 else
148 entry.push_back(Pair("confirmations", 0));
149 }
150 }
151}
152
153Value getrawtransaction(const Array& params, bool fHelp)
154{
155 if (fHelp || params.size() < 1 || params.size() > 2)
156 throw runtime_error(
a6099ef3 157 "getrawtransaction \"txid\" ( verbose )\n"
3e61eb9c
CL
158 "\nNOTE: By default this function only works sometimes. This is when the tx is in the mempool\n"
159 "or there is an unspent output in the utxo for this transaction. To make it always work,\n"
160 "you need to maintain a transaction index, using the -txindex command line option.\n"
a6099ef3 161 "\nReturn the raw transaction data.\n"
162 "\nIf verbose=0, returns a string that is serialized, hex-encoded data for 'txid'.\n"
163 "If verbose is non-zero, returns an Object with information about 'txid'.\n"
164
165 "\nArguments:\n"
166 "1. \"txid\" (string, required) The transaction id\n"
167 "2. verbose (numeric, optional, default=0) If 0, return a string, other return a json object\n"
168
169 "\nResult (if verbose is not set or set to 0):\n"
170 "\"data\" (string) The serialized, hex-encoded data for 'txid'\n"
171
172 "\nResult (if verbose > 0):\n"
173 "{\n"
174 " \"hex\" : \"data\", (string) The serialized, hex-encoded data for 'txid'\n"
175 " \"txid\" : \"id\", (string) The transaction id (same as provided)\n"
176 " \"version\" : n, (numeric) The version\n"
177 " \"locktime\" : ttt, (numeric) The lock time\n"
178 " \"vin\" : [ (array of json objects)\n"
179 " {\n"
180 " \"txid\": \"id\", (string) The transaction id\n"
181 " \"vout\": n, (numeric) \n"
182 " \"scriptSig\": { (json object) The script\n"
183 " \"asm\": \"asm\", (string) asm\n"
184 " \"hex\": \"hex\" (string) hex\n"
185 " },\n"
186 " \"sequence\": n (numeric) The script sequence number\n"
187 " }\n"
188 " ,...\n"
189 " ],\n"
190 " \"vout\" : [ (array of json objects)\n"
191 " {\n"
192 " \"value\" : x.xxx, (numeric) The value in btc\n"
193 " \"n\" : n, (numeric) index\n"
194 " \"scriptPubKey\" : { (json object)\n"
195 " \"asm\" : \"asm\", (string) the asm\n"
196 " \"hex\" : \"hex\", (string) the hex\n"
197 " \"reqSigs\" : n, (numeric) The required sigs\n"
198 " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
199 " \"addresses\" : [ (json array of string)\n"
200 " \"bitcoinaddress\" (string) bitcoin address\n"
201 " ,...\n"
202 " ]\n"
203 " }\n"
204 " }\n"
205 " ,...\n"
206 " ],\n"
207 " \"blockhash\" : \"hash\", (string) the block hash\n"
208 " \"confirmations\" : n, (numeric) The confirmations\n"
209 " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT)\n"
210 " \"blocktime\" : ttt (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
211 "}\n"
212
213 "\nExamples:\n"
214 + HelpExampleCli("getrawtransaction", "\"mytxid\"")
215 + HelpExampleCli("getrawtransaction", "\"mytxid\" 1")
216 + HelpExampleRpc("getrawtransaction", "\"mytxid\", 1")
217 );
a2709fad 218
4401b2d7
EL
219 LOCK(cs_main);
220
2d43f88e 221 uint256 hash = ParseHashV(params[0], "parameter 1");
a2709fad
GA
222
223 bool fVerbose = false;
224 if (params.size() > 1)
225 fVerbose = (params[1].get_int() != 0);
226
227 CTransaction tx;
4f152496 228 uint256 hashBlock;
450cbb09 229 if (!GetTransaction(hash, tx, hashBlock, true))
738835d7 230 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction");
a2709fad 231
ae775b5b 232 string strHex = EncodeHexTx(tx);
a2709fad
GA
233
234 if (!fVerbose)
235 return strHex;
236
237 Object result;
238 result.push_back(Pair("hex", strHex));
239 TxToJSON(tx, hashBlock, result);
240 return result;
241}
242
59ed61b3
MC
243Value gettxoutproof(const Array& params, bool fHelp)
244{
245 if (fHelp || (params.size() != 1 && params.size() != 2))
246 throw runtime_error(
247 "gettxoutproof [\"txid\",...] ( blockhash )\n"
248 "\nReturns a hex-encoded proof that \"txid\" was included in a block.\n"
249 "\nNOTE: By default this function only works sometimes. This is when there is an\n"
250 "unspent output in the utxo for this transaction. To make it always work,\n"
251 "you need to maintain a transaction index, using the -txindex command line option or\n"
252 "specify the block in which the transaction is included in manually (by blockhash).\n"
253 "\nReturn the raw transaction data.\n"
254 "\nArguments:\n"
255 "1. \"txids\" (string) A json array of txids to filter\n"
256 " [\n"
257 " \"txid\" (string) A transaction hash\n"
258 " ,...\n"
259 " ]\n"
260 "2. \"block hash\" (string, optional) If specified, looks for txid in the block with this hash\n"
261 "\nResult:\n"
262 "\"data\" (string) A string that is a serialized, hex-encoded data for the proof.\n"
263 );
264
265 set<uint256> setTxids;
266 uint256 oneTxid;
267 Array txids = params[0].get_array();
268 BOOST_FOREACH(Value& txid, txids) {
269 if (txid.get_str().length() != 64 || !IsHex(txid.get_str()))
270 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid txid ")+txid.get_str());
271 uint256 hash(uint256S(txid.get_str()));
272 if (setTxids.count(hash))
273 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated txid: ")+txid.get_str());
274 setTxids.insert(hash);
275 oneTxid = hash;
276 }
277
278 LOCK(cs_main);
279
280 CBlockIndex* pblockindex = NULL;
281
282 uint256 hashBlock;
283 if (params.size() > 1)
284 {
285 hashBlock = uint256S(params[1].get_str());
286 if (!mapBlockIndex.count(hashBlock))
287 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
288 pblockindex = mapBlockIndex[hashBlock];
289 } else {
290 CCoins coins;
291 if (pcoinsTip->GetCoins(oneTxid, coins) && coins.nHeight > 0 && coins.nHeight <= chainActive.Height())
292 pblockindex = chainActive[coins.nHeight];
293 }
294
295 if (pblockindex == NULL)
296 {
297 CTransaction tx;
298 if (!GetTransaction(oneTxid, tx, hashBlock, false) || hashBlock.IsNull())
299 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block");
300 if (!mapBlockIndex.count(hashBlock))
301 throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt");
302 pblockindex = mapBlockIndex[hashBlock];
303 }
304
305 CBlock block;
306 if(!ReadBlockFromDisk(block, pblockindex))
307 throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
308
309 unsigned int ntxFound = 0;
310 BOOST_FOREACH(const CTransaction&tx, block.vtx)
805344dc 311 if (setTxids.count(tx.GetHash()))
59ed61b3
MC
312 ntxFound++;
313 if (ntxFound != setTxids.size())
314 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "(Not all) transactions not found in specified block");
315
316 CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION);
317 CMerkleBlock mb(block, setTxids);
318 ssMB << mb;
319 std::string strHex = HexStr(ssMB.begin(), ssMB.end());
320 return strHex;
321}
322
323Value verifytxoutproof(const Array& params, bool fHelp)
324{
325 if (fHelp || params.size() != 1)
326 throw runtime_error(
327 "verifytxoutproof \"proof\"\n"
328 "\nVerifies that a proof points to a transaction in a block, returning the transaction it commits to\n"
329 "and throwing an RPC error if the block is not in our best chain\n"
330 "\nArguments:\n"
331 "1. \"proof\" (string, required) The hex-encoded proof generated by gettxoutproof\n"
332 "\nResult:\n"
333 "[\"txid\"] (array, strings) The txid(s) which the proof commits to, or empty array if the proof is invalid\n"
334 );
335
336 CDataStream ssMB(ParseHexV(params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION);
337 CMerkleBlock merkleBlock;
338 ssMB >> merkleBlock;
339
340 Array res;
341
342 vector<uint256> vMatch;
343 if (merkleBlock.txn.ExtractMatches(vMatch) != merkleBlock.header.hashMerkleRoot)
344 return res;
345
346 LOCK(cs_main);
347
348 if (!mapBlockIndex.count(merkleBlock.header.GetHash()) || !chainActive.Contains(mapBlockIndex[merkleBlock.header.GetHash()]))
349 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain");
350
351 BOOST_FOREACH(const uint256& hash, vMatch)
352 res.push_back(hash.GetHex());
353 return res;
354}
355
a2709fad
GA
356Value createrawtransaction(const Array& params, bool fHelp)
357{
358 if (fHelp || params.size() != 2)
359 throw runtime_error(
a6099ef3 360 "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,...}\n"
361 "\nCreate a transaction spending the given inputs and sending to the given addresses.\n"
a2709fad
GA
362 "Returns hex-encoded raw transaction.\n"
363 "Note that the transaction's inputs are not signed, and\n"
a6099ef3 364 "it is not stored in the wallet or transmitted to the network.\n"
365
366 "\nArguments:\n"
367 "1. \"transactions\" (string, required) A json array of json objects\n"
368 " [\n"
369 " {\n"
370 " \"txid\":\"id\", (string, required) The transaction id\n"
371 " \"vout\":n (numeric, required) The output number\n"
372 " }\n"
373 " ,...\n"
374 " ]\n"
375 "2. \"addresses\" (string, required) a json object with addresses as keys and amounts as values\n"
376 " {\n"
377 " \"address\": x.xxx (numeric, required) The key is the bitcoin address, the value is the btc amount\n"
378 " ,...\n"
379 " }\n"
380
381 "\nResult:\n"
382 "\"transaction\" (string) hex string of the transaction\n"
383
384 "\nExamples\n"
385 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":0.01}\"")
386 + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\"")
387 );
a2709fad 388
4401b2d7 389 LOCK(cs_main);
856e862f 390 RPCTypeCheck(params, boost::assign::list_of(array_type)(obj_type));
a2709fad
GA
391
392 Array inputs = params[0].get_array();
393 Object sendTo = params[1].get_obj();
394
4949004d 395 CMutableTransaction rawTx;
a2709fad 396
3ce7e669 397 BOOST_FOREACH(const Value& input, inputs) {
a2709fad
GA
398 const Object& o = input.get_obj();
399
2d43f88e 400 uint256 txid = ParseHashO(o, "txid");
a2709fad
GA
401
402 const Value& vout_v = find_value(o, "vout");
403 if (vout_v.type() != int_type)
738835d7 404 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");
a2709fad
GA
405 int nOutput = vout_v.get_int();
406 if (nOutput < 0)
738835d7 407 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
a2709fad 408
2d43f88e 409 CTxIn in(COutPoint(txid, nOutput));
a2709fad
GA
410 rawTx.vin.push_back(in);
411 }
412
413 set<CBitcoinAddress> setAddress;
3ce7e669 414 BOOST_FOREACH(const Pair& s, sendTo) {
a2709fad
GA
415 CBitcoinAddress address(s.name_);
416 if (!address.IsValid())
738835d7 417 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+s.name_);
a2709fad
GA
418
419 if (setAddress.count(address))
738835d7 420 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_);
a2709fad
GA
421 setAddress.insert(address);
422
0be990ba 423 CScript scriptPubKey = GetScriptForDestination(address.Get());
a372168e 424 CAmount nAmount = AmountFromValue(s.value_);
a2709fad
GA
425
426 CTxOut out(nAmount, scriptPubKey);
427 rawTx.vout.push_back(out);
428 }
429
ae775b5b 430 return EncodeHexTx(rawTx);
a2709fad
GA
431}
432
433Value decoderawtransaction(const Array& params, bool fHelp)
434{
435 if (fHelp || params.size() != 1)
436 throw runtime_error(
a6099ef3 437 "decoderawtransaction \"hexstring\"\n"
438 "\nReturn a JSON object representing the serialized, hex-encoded transaction.\n"
439
440 "\nArguments:\n"
e0c06d2c 441 "1. \"hex\" (string, required) The transaction hex string\n"
a6099ef3 442
443 "\nResult:\n"
444 "{\n"
e0c06d2c 445 " \"txid\" : \"id\", (string) The transaction id\n"
a6099ef3 446 " \"version\" : n, (numeric) The version\n"
447 " \"locktime\" : ttt, (numeric) The lock time\n"
448 " \"vin\" : [ (array of json objects)\n"
449 " {\n"
450 " \"txid\": \"id\", (string) The transaction id\n"
451 " \"vout\": n, (numeric) The output number\n"
452 " \"scriptSig\": { (json object) The script\n"
453 " \"asm\": \"asm\", (string) asm\n"
454 " \"hex\": \"hex\" (string) hex\n"
455 " },\n"
456 " \"sequence\": n (numeric) The script sequence number\n"
457 " }\n"
458 " ,...\n"
459 " ],\n"
460 " \"vout\" : [ (array of json objects)\n"
461 " {\n"
462 " \"value\" : x.xxx, (numeric) The value in btc\n"
463 " \"n\" : n, (numeric) index\n"
464 " \"scriptPubKey\" : { (json object)\n"
465 " \"asm\" : \"asm\", (string) the asm\n"
466 " \"hex\" : \"hex\", (string) the hex\n"
467 " \"reqSigs\" : n, (numeric) The required sigs\n"
468 " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
469 " \"addresses\" : [ (json array of string)\n"
470 " \"12tvKAXCxZjSmdNbao16dKXC8tRWfcF5oc\" (string) bitcoin address\n"
471 " ,...\n"
472 " ]\n"
473 " }\n"
474 " }\n"
475 " ,...\n"
476 " ],\n"
a6099ef3 477 "}\n"
478
479 "\nExamples:\n"
480 + HelpExampleCli("decoderawtransaction", "\"hexstring\"")
481 + HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
482 );
a2709fad 483
4401b2d7 484 LOCK(cs_main);
856e862f 485 RPCTypeCheck(params, boost::assign::list_of(str_type));
ae775b5b 486
a2709fad 487 CTransaction tx;
ae775b5b
JG
488
489 if (!DecodeHexTx(tx, params[0].get_str()))
738835d7 490 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
a2709fad
GA
491
492 Object result;
4f152496 493 TxToJSON(tx, uint256(), result);
a2709fad
GA
494
495 return result;
496}
497
be066fad
PT
498Value decodescript(const Array& params, bool fHelp)
499{
500 if (fHelp || params.size() != 1)
501 throw runtime_error(
a6099ef3 502 "decodescript \"hex\"\n"
503 "\nDecode a hex-encoded script.\n"
504 "\nArguments:\n"
505 "1. \"hex\" (string) the hex encoded script\n"
506 "\nResult:\n"
507 "{\n"
508 " \"asm\":\"asm\", (string) Script public key\n"
509 " \"hex\":\"hex\", (string) hex encoded public key\n"
510 " \"type\":\"type\", (string) The output type\n"
511 " \"reqSigs\": n, (numeric) The required signatures\n"
512 " \"addresses\": [ (json array of string)\n"
513 " \"address\" (string) bitcoin address\n"
514 " ,...\n"
515 " ],\n"
516 " \"p2sh\",\"address\" (string) script address\n"
517 "}\n"
518 "\nExamples:\n"
519 + HelpExampleCli("decodescript", "\"hexstring\"")
520 + HelpExampleRpc("decodescript", "\"hexstring\"")
521 );
be066fad 522
4401b2d7 523 LOCK(cs_main);
856e862f 524 RPCTypeCheck(params, boost::assign::list_of(str_type));
be066fad
PT
525
526 Object r;
527 CScript script;
528 if (params[0].get_str().size() > 0){
529 vector<unsigned char> scriptData(ParseHexV(params[0], "argument"));
530 script = CScript(scriptData.begin(), scriptData.end());
531 } else {
532 // Empty scripts are valid
533 }
534 ScriptPubKeyToJSON(script, r, false);
535
066e2a14 536 r.push_back(Pair("p2sh", CBitcoinAddress(CScriptID(script)).ToString()));
be066fad
PT
537 return r;
538}
539
8ac2a4e1 540/** Pushes a JSON object for script verification or signing errors to vErrorsRet. */
541static void TxInErrorToJSON(const CTxIn& txin, Array& vErrorsRet, const std::string& strMessage)
542{
543 Object entry;
544 entry.push_back(Pair("txid", txin.prevout.hash.ToString()));
545 entry.push_back(Pair("vout", (uint64_t)txin.prevout.n));
546 entry.push_back(Pair("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
547 entry.push_back(Pair("sequence", (uint64_t)txin.nSequence));
548 entry.push_back(Pair("error", strMessage));
549 vErrorsRet.push_back(entry);
550}
551
a2709fad
GA
552Value signrawtransaction(const Array& params, bool fHelp)
553{
3c3666d6 554 if (fHelp || params.size() < 1 || params.size() > 4)
a2709fad 555 throw runtime_error(
a6099ef3 556 "signrawtransaction \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] [\"privatekey1\",...] sighashtype )\n"
557 "\nSign inputs for raw transaction (serialized, hex-encoded).\n"
558 "The second optional argument (may be null) is an array of previous transaction outputs that\n"
729b1806 559 "this transaction depends on but may not yet be in the block chain.\n"
a6099ef3 560 "The third optional argument (may be null) is an array of base58-encoded private\n"
a2709fad 561 "keys that, if given, will be the only keys used to sign the transaction.\n"
48ba56cd 562#ifdef ENABLE_WALLET
a6099ef3 563 + HelpRequiringPassphrase() + "\n"
48ba56cd 564#endif
a6099ef3 565
566 "\nArguments:\n"
567 "1. \"hexstring\" (string, required) The transaction hex string\n"
568 "2. \"prevtxs\" (string, optional) An json array of previous dependent transaction outputs\n"
041f71bb 569 " [ (json array of json objects, or 'null' if none provided)\n"
a6099ef3 570 " {\n"
571 " \"txid\":\"id\", (string, required) The transaction id\n"
572 " \"vout\":n, (numeric, required) The output number\n"
573 " \"scriptPubKey\": \"hex\", (string, required) script key\n"
6265ecc8 574 " \"redeemScript\": \"hex\" (string, required for P2SH) redeem script\n"
a6099ef3 575 " }\n"
576 " ,...\n"
577 " ]\n"
578 "3. \"privatekeys\" (string, optional) A json array of base58-encoded private keys for signing\n"
041f71bb 579 " [ (json array of strings, or 'null' if none provided)\n"
a6099ef3 580 " \"privatekey\" (string) private key in base58-encoding\n"
581 " ,...\n"
582 " ]\n"
ab643811 583 "4. \"sighashtype\" (string, optional, default=ALL) The signature hash type. Must be one of\n"
a6099ef3 584 " \"ALL\"\n"
585 " \"NONE\"\n"
586 " \"SINGLE\"\n"
587 " \"ALL|ANYONECANPAY\"\n"
588 " \"NONE|ANYONECANPAY\"\n"
589 " \"SINGLE|ANYONECANPAY\"\n"
590
591 "\nResult:\n"
592 "{\n"
8ac2a4e1 593 " \"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n"
594 " \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n"
595 " \"errors\" : [ (json array of objects) Script verification errors (if there are any)\n"
596 " {\n"
597 " \"txid\" : \"hash\", (string) The hash of the referenced, previous transaction\n"
598 " \"vout\" : n, (numeric) The index of the output to spent and used as input\n"
599 " \"scriptSig\" : \"hex\", (string) The hex-encoded signature script\n"
600 " \"sequence\" : n, (numeric) Script sequence number\n"
601 " \"error\" : \"text\" (string) Verification or signing error related to the input\n"
602 " }\n"
603 " ,...\n"
604 " ]\n"
a6099ef3 605 "}\n"
606
607 "\nExamples:\n"
608 + HelpExampleCli("signrawtransaction", "\"myhex\"")
609 + HelpExampleRpc("signrawtransaction", "\"myhex\"")
610 );
a2709fad 611
4401b2d7
EL
612#ifdef ENABLE_WALLET
613 LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
614#else
615 LOCK(cs_main);
616#endif
856e862f 617 RPCTypeCheck(params, boost::assign::list_of(str_type)(array_type)(array_type)(str_type), true);
a2709fad 618
2d43f88e 619 vector<unsigned char> txData(ParseHexV(params[0], "argument 1"));
a2709fad 620 CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
4949004d 621 vector<CMutableTransaction> txVariants;
3ce7e669 622 while (!ssData.empty()) {
a2709fad 623 try {
4949004d 624 CMutableTransaction tx;
a2709fad
GA
625 ssData >> tx;
626 txVariants.push_back(tx);
627 }
27df4123 628 catch (const std::exception&) {
738835d7 629 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
a2709fad
GA
630 }
631 }
632
633 if (txVariants.empty())
738835d7 634 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transaction");
a2709fad
GA
635
636 // mergedTx will end up with all the signatures; it
637 // starts as a clone of the rawtx:
4949004d 638 CMutableTransaction mergedTx(txVariants[0]);
a2709fad
GA
639
640 // Fetch previous transactions (inputs):
450cbb09 641 CCoinsView viewDummy;
7c70438d 642 CCoinsViewCache view(&viewDummy);
a2709fad 643 {
450cbb09 644 LOCK(mempool.cs);
ae8bfd12 645 CCoinsViewCache &viewChain = *pcoinsTip;
7c70438d 646 CCoinsViewMemPool viewMempool(&viewChain, mempool);
450cbb09
PW
647 view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
648
649 BOOST_FOREACH(const CTxIn& txin, mergedTx.vin) {
a2709fad 650 const uint256& prevHash = txin.prevout.hash;
450cbb09 651 CCoins coins;
629d75fa 652 view.AccessCoins(prevHash); // this is certainly allowed to fail
a2709fad 653 }
450cbb09 654
ae8bfd12 655 view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
a2709fad
GA
656 }
657
03346a61
GA
658 bool fGivenKeys = false;
659 CBasicKeyStore tempKeystore;
3ce7e669 660 if (params.size() > 2 && params[2].type() != null_type) {
03346a61
GA
661 fGivenKeys = true;
662 Array keys = params[2].get_array();
3ce7e669 663 BOOST_FOREACH(Value k, keys) {
03346a61
GA
664 CBitcoinSecret vchSecret;
665 bool fGood = vchSecret.SetString(k.get_str());
666 if (!fGood)
667 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
dfa23b94 668 CKey key = vchSecret.GetKey();
aa768f18
PJ
669 if (!key.IsValid())
670 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
03346a61
GA
671 tempKeystore.AddKey(key);
672 }
673 }
48ba56cd 674#ifdef ENABLE_WALLET
4401b2d7 675 else if (pwalletMain)
03346a61 676 EnsureWalletIsUnlocked();
48ba56cd 677#endif
03346a61 678
a2709fad 679 // Add previous txouts given in the RPC call:
3ce7e669 680 if (params.size() > 1 && params[1].type() != null_type) {
a2709fad 681 Array prevTxs = params[1].get_array();
3ce7e669 682 BOOST_FOREACH(Value& p, prevTxs) {
a2709fad 683 if (p.type() != obj_type)
738835d7 684 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}");
a2709fad
GA
685
686 Object prevOut = p.get_obj();
687
856e862f 688 RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type));
a2709fad 689
2d43f88e 690 uint256 txid = ParseHashO(prevOut, "txid");
a2709fad
GA
691
692 int nOut = find_value(prevOut, "vout").get_int();
693 if (nOut < 0)
738835d7 694 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout must be positive");
a2709fad 695
2d43f88e 696 vector<unsigned char> pkData(ParseHexO(prevOut, "scriptPubKey"));
a2709fad
GA
697 CScript scriptPubKey(pkData.begin(), pkData.end());
698
f28aec01
PW
699 {
700 CCoinsModifier coins = view.ModifyCoins(txid);
701 if (coins->IsAvailable(nOut) && coins->vout[nOut].scriptPubKey != scriptPubKey) {
a2709fad 702 string err("Previous output scriptPubKey mismatch:\n");
f28aec01 703 err = err + coins->vout[nOut].scriptPubKey.ToString() + "\nvs:\n"+
a2709fad 704 scriptPubKey.ToString();
738835d7 705 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err);
a2709fad 706 }
f28aec01
PW
707 if ((unsigned int)nOut >= coins->vout.size())
708 coins->vout.resize(nOut+1);
709 coins->vout[nOut].scriptPubKey = scriptPubKey;
710 coins->vout[nOut].nValue = 0; // we don't know the actual output value
a2709fad 711 }
a2709fad 712
03346a61
GA
713 // if redeemScript given and not using the local wallet (private keys
714 // given), add redeemScript to the tempKeystore so it can be signed:
3ce7e669 715 if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) {
856e862f 716 RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)("redeemScript",str_type));
21c6d3ae 717 Value v = find_value(prevOut, "redeemScript");
3ce7e669 718 if (!(v == Value::null)) {
21c6d3ae
GM
719 vector<unsigned char> rsData(ParseHexV(v, "redeemScript"));
720 CScript redeemScript(rsData.begin(), rsData.end());
721 tempKeystore.AddCScript(redeemScript);
722 }
03346a61 723 }
a2709fad
GA
724 }
725 }
cc6dfd1f 726
48ba56cd 727#ifdef ENABLE_WALLET
b0730874 728 const CKeyStore& keystore = ((fGivenKeys || !pwalletMain) ? tempKeystore : *pwalletMain);
48ba56cd
WL
729#else
730 const CKeyStore& keystore = tempKeystore;
731#endif
a2709fad 732
3c3666d6 733 int nHashType = SIGHASH_ALL;
3ce7e669 734 if (params.size() > 3 && params[3].type() != null_type) {
3c3666d6
GA
735 static map<string, int> mapSigHashValues =
736 boost::assign::map_list_of
737 (string("ALL"), int(SIGHASH_ALL))
738 (string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY))
739 (string("NONE"), int(SIGHASH_NONE))
740 (string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY))
741 (string("SINGLE"), int(SIGHASH_SINGLE))
742 (string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY))
743 ;
744 string strHashType = params[3].get_str();
745 if (mapSigHashValues.count(strHashType))
746 nHashType = mapSigHashValues[strHashType];
747 else
738835d7 748 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param");
3c3666d6
GA
749 }
750
d5e7b611
GA
751 bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
752
8ac2a4e1 753 // Script verification errors
754 Array vErrors;
755
a2709fad 756 // Sign what we can:
3ce7e669 757 for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
a2709fad 758 CTxIn& txin = mergedTx.vin[i];
629d75fa
PW
759 const CCoins* coins = view.AccessCoins(txin.prevout.hash);
760 if (coins == NULL || !coins->IsAvailable(txin.prevout.n)) {
8ac2a4e1 761 TxInErrorToJSON(txin, vErrors, "Input not found or already spent");
a2709fad
GA
762 continue;
763 }
629d75fa 764 const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey;
a2709fad
GA
765
766 txin.scriptSig.clear();
d5e7b611
GA
767 // Only sign SIGHASH_SINGLE if there's a corresponding output:
768 if (!fHashSingle || (i < mergedTx.vout.size()))
769 SignSignature(keystore, prevPubKey, mergedTx, i, nHashType);
a2709fad
GA
770
771 // ... and merge in other signatures:
3ce7e669 772 BOOST_FOREACH(const CMutableTransaction& txv, txVariants) {
a2709fad
GA
773 txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig);
774 }
8ac2a4e1 775 ScriptError serror = SCRIPT_ERR_OK;
776 if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i), &serror)) {
777 TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror));
778 }
a2709fad 779 }
8ac2a4e1 780 bool fComplete = vErrors.empty();
a2709fad
GA
781
782 Object result;
ae775b5b 783 result.push_back(Pair("hex", EncodeHexTx(mergedTx)));
a2709fad 784 result.push_back(Pair("complete", fComplete));
8ac2a4e1 785 if (!vErrors.empty()) {
786 result.push_back(Pair("errors", vErrors));
787 }
a2709fad
GA
788
789 return result;
790}
791
792Value sendrawtransaction(const Array& params, bool fHelp)
793{
9d14e689 794 if (fHelp || params.size() < 1 || params.size() > 2)
a2709fad 795 throw runtime_error(
a6099ef3 796 "sendrawtransaction \"hexstring\" ( allowhighfees )\n"
797 "\nSubmits raw transaction (serialized, hex-encoded) to local node and network.\n"
798 "\nAlso see createrawtransaction and signrawtransaction calls.\n"
799 "\nArguments:\n"
800 "1. \"hexstring\" (string, required) The hex string of the raw transaction)\n"
801 "2. allowhighfees (boolean, optional, default=false) Allow high fees\n"
802 "\nResult:\n"
803 "\"hex\" (string) The transaction hash in hex\n"
804 "\nExamples:\n"
805 "\nCreate a transaction\n"
806 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") +
807 "Sign the transaction, and get back the hex\n"
808 + HelpExampleCli("signrawtransaction", "\"myhex\"") +
809 "\nSend the transaction (signed hex)\n"
810 + HelpExampleCli("sendrawtransaction", "\"signedhex\"") +
811 "\nAs a json rpc call\n"
812 + HelpExampleRpc("sendrawtransaction", "\"signedhex\"")
813 );
814
4401b2d7 815 LOCK(cs_main);
856e862f 816 RPCTypeCheck(params, boost::assign::list_of(str_type)(bool_type));
a2709fad 817
a2709fad 818 // parse hex string from parameter
a2709fad 819 CTransaction tx;
ae775b5b
JG
820 if (!DecodeHexTx(tx, params[0].get_str()))
821 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
805344dc 822 uint256 hashTx = tx.GetHash();
a2709fad 823
9d14e689
GM
824 bool fOverrideFees = false;
825 if (params.size() > 1)
826 fOverrideFees = params[1].get_bool();
827
ae8bfd12 828 CCoinsViewCache &view = *pcoinsTip;
629d75fa 829 const CCoins* existingCoins = view.AccessCoins(hashTx);
1d46fe33 830 bool fHaveMempool = mempool.exists(hashTx);
629d75fa 831 bool fHaveChain = existingCoins && existingCoins->nHeight < 1000000000;
1d46fe33
WL
832 if (!fHaveMempool && !fHaveChain) {
833 // push to local node and sync with wallets
834 CValidationState state;
de8e801d
PW
835 bool fMissingInputs;
836 if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees)) {
837 if (state.IsInvalid()) {
1d46fe33 838 throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
de8e801d
PW
839 } else {
840 if (fMissingInputs) {
841 throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs");
842 }
1d46fe33 843 throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason());
de8e801d 844 }
450cbb09 845 }
1d46fe33
WL
846 } else if (fHaveChain) {
847 throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain");
771ffb5e 848 }
d38da59b 849 RelayTransaction(tx);
a2709fad 850
771ffb5e 851 return hashTx.GetHex();
a2709fad 852}
This page took 0.284756 seconds and 4 git commands to generate.