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.
5
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 "rpc/server.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
29
30 #include <stdint.h>
31
32 #include <boost/assign/list_of.hpp>
33
34 #include <univalue.h>
35
36 using namespace std;
37
ScriptPubKeyToJSON(const CScript & scriptPubKey,UniValue & out,bool fIncludeHex)38 void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex)
39 {
40 txnouttype type;
41 vector<CTxDestination> addresses;
42 int nRequired;
43
44 out.push_back(Pair("asm", ScriptToAsmStr(scriptPubKey)));
45 if (fIncludeHex)
46 out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
47
48 if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) {
49 out.push_back(Pair("type", GetTxnOutputType(type)));
50 return;
51 }
52
53 out.push_back(Pair("reqSigs", nRequired));
54 out.push_back(Pair("type", GetTxnOutputType(type)));
55
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));
60 }
61
TxToJSON(const CTransaction & tx,const uint256 hashBlock,UniValue & entry)62 void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
63 {
64 entry.push_back(Pair("txid", tx.GetHash().GetHex()));
65 entry.push_back(Pair("hash", tx.GetWitnessHash().GetHex()));
66 entry.push_back(Pair("size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION)));
67 entry.push_back(Pair("vsize", (int)::GetVirtualTransactionSize(tx)));
68 entry.push_back(Pair("version", tx.nVersion));
69 entry.push_back(Pair("locktime", (int64_t)tx.nLockTime));
70
71 UniValue vin(UniValue::VARR);
72 for (unsigned int i = 0; i < tx.vin.size(); i++) {
73 const CTxIn& txin = tx.vin[i];
74 UniValue in(UniValue::VOBJ);
75 if (tx.IsCoinBase())
76 in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
77 else {
78 in.push_back(Pair("txid", txin.prevout.hash.GetHex()));
79 in.push_back(Pair("vout", (int64_t)txin.prevout.n));
80 UniValue o(UniValue::VOBJ);
81 o.push_back(Pair("asm", ScriptToAsmStr(txin.scriptSig, true)));
82 o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
83 in.push_back(Pair("scriptSig", o));
84 }
85 if (!tx.wit.IsNull()) {
86 if (!tx.wit.vtxinwit[i].IsNull()) {
87 UniValue txinwitness(UniValue::VARR);
88 for (unsigned int j = 0; j < tx.wit.vtxinwit[i].scriptWitness.stack.size(); j++) {
89 std::vector<unsigned char> item = tx.wit.vtxinwit[i].scriptWitness.stack[j];
90 txinwitness.push_back(HexStr(item.begin(), item.end()));
91 }
92 in.push_back(Pair("txinwitness", txinwitness));
93 }
94
95 }
96 in.push_back(Pair("sequence", (int64_t)txin.nSequence));
97 vin.push_back(in);
98 }
99 entry.push_back(Pair("vin", vin));
100 UniValue vout(UniValue::VARR);
101 for (unsigned int i = 0; i < tx.vout.size(); i++) {
102 const CTxOut& txout = tx.vout[i];
103 UniValue out(UniValue::VOBJ);
104 out.push_back(Pair("value", ValueFromAmount(txout.nValue)));
105 out.push_back(Pair("n", (int64_t)i));
106 UniValue o(UniValue::VOBJ);
107 ScriptPubKeyToJSON(txout.scriptPubKey, o, true);
108 out.push_back(Pair("scriptPubKey", o));
109 vout.push_back(out);
110 }
111 entry.push_back(Pair("vout", vout));
112
113 if (!hashBlock.IsNull()) {
114 entry.push_back(Pair("blockhash", hashBlock.GetHex()));
115 BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
116 if (mi != mapBlockIndex.end() && (*mi).second) {
117 CBlockIndex* pindex = (*mi).second;
118 if (chainActive.Contains(pindex)) {
119 entry.push_back(Pair("confirmations", 1 + chainActive.Height() - pindex->nHeight));
120 entry.push_back(Pair("time", pindex->GetBlockTime()));
121 entry.push_back(Pair("blocktime", pindex->GetBlockTime()));
122 }
123 else
124 entry.push_back(Pair("confirmations", 0));
125 }
126 }
127 }
128
getrawtransaction(const UniValue & params,bool fHelp)129 UniValue getrawtransaction(const UniValue& params, bool fHelp)
130 {
131 if (fHelp || params.size() < 1 || params.size() > 2)
132 throw runtime_error(
133 "getrawtransaction \"txid\" ( verbose )\n"
134 "\nNOTE: By default this function only works sometimes. This is when the tx is in the mempool\n"
135 "or there is an unspent output in the utxo for this transaction. To make it always work,\n"
136 "you need to maintain a transaction index, using the -txindex command line option.\n"
137 "\nReturn the raw transaction data.\n"
138 "\nIf verbose=0, returns a string that is serialized, hex-encoded data for 'txid'.\n"
139 "If verbose is non-zero, returns an Object with information about 'txid'.\n"
140
141 "\nArguments:\n"
142 "1. \"txid\" (string, required) The transaction id\n"
143 "2. verbose (numeric, optional, default=0) If 0, return a string, other return a json object\n"
144
145 "\nResult (if verbose is not set or set to 0):\n"
146 "\"data\" (string) The serialized, hex-encoded data for 'txid'\n"
147
148 "\nResult (if verbose > 0):\n"
149 "{\n"
150 " \"hex\" : \"data\", (string) The serialized, hex-encoded data for 'txid'\n"
151 " \"txid\" : \"id\", (string) The transaction id (same as provided)\n"
152 " \"hash\" : \"id\", (string) The transaction hash (differs from txid for witness transactions)\n"
153 " \"size\" : n, (numeric) The serialized transaction size\n"
154 " \"vsize\" : n, (numeric) The virtual transaction size (differs from size for witness transactions)\n"
155 " \"version\" : n, (numeric) The version\n"
156 " \"locktime\" : ttt, (numeric) The lock time\n"
157 " \"vin\" : [ (array of json objects)\n"
158 " {\n"
159 " \"txid\": \"id\", (string) The transaction id\n"
160 " \"vout\": n, (numeric) \n"
161 " \"scriptSig\": { (json object) The script\n"
162 " \"asm\": \"asm\", (string) asm\n"
163 " \"hex\": \"hex\" (string) hex\n"
164 " },\n"
165 " \"sequence\": n (numeric) The script sequence number\n"
166 " \"txinwitness\": [\"hex\", ...] (array of string) hex-encoded witness data (if any)\n"
167 " }\n"
168 " ,...\n"
169 " ],\n"
170 " \"vout\" : [ (array of json objects)\n"
171 " {\n"
172 " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n"
173 " \"n\" : n, (numeric) index\n"
174 " \"scriptPubKey\" : { (json object)\n"
175 " \"asm\" : \"asm\", (string) the asm\n"
176 " \"hex\" : \"hex\", (string) the hex\n"
177 " \"reqSigs\" : n, (numeric) The required sigs\n"
178 " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
179 " \"addresses\" : [ (json array of string)\n"
180 " \"zetacoinaddress\" (string) zetacoin address\n"
181 " ,...\n"
182 " ]\n"
183 " }\n"
184 " }\n"
185 " ,...\n"
186 " ],\n"
187 " \"blockhash\" : \"hash\", (string) the block hash\n"
188 " \"confirmations\" : n, (numeric) The confirmations\n"
189 " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT)\n"
190 " \"blocktime\" : ttt (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
191 "}\n"
192
193 "\nExamples:\n"
194 + HelpExampleCli("getrawtransaction", "\"mytxid\"")
195 + HelpExampleCli("getrawtransaction", "\"mytxid\" 1")
196 + HelpExampleRpc("getrawtransaction", "\"mytxid\", 1")
197 );
198
199 LOCK(cs_main);
200
201 uint256 hash = ParseHashV(params[0], "parameter 1");
202
203 bool fVerbose = false;
204 if (params.size() > 1)
205 fVerbose = (params[1].get_int() != 0);
206
207 CTransaction tx;
208 uint256 hashBlock;
209 if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true))
210 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction");
211
212 string strHex = EncodeHexTx(tx, RPCSerializationFlags());
213
214 if (!fVerbose)
215 return strHex;
216
217 UniValue result(UniValue::VOBJ);
218 result.push_back(Pair("hex", strHex));
219 TxToJSON(tx, hashBlock, result);
220 return result;
221 }
222
gettxoutproof(const UniValue & params,bool fHelp)223 UniValue gettxoutproof(const UniValue& params, bool fHelp)
224 {
225 if (fHelp || (params.size() != 1 && params.size() != 2))
226 throw runtime_error(
227 "gettxoutproof [\"txid\",...] ( blockhash )\n"
228 "\nReturns a hex-encoded proof that \"txid\" was included in a block.\n"
229 "\nNOTE: By default this function only works sometimes. This is when there is an\n"
230 "unspent output in the utxo for this transaction. To make it always work,\n"
231 "you need to maintain a transaction index, using the -txindex command line option or\n"
232 "specify the block in which the transaction is included manually (by blockhash).\n"
233 "\nReturn the raw transaction data.\n"
234 "\nArguments:\n"
235 "1. \"txids\" (string) A json array of txids to filter\n"
236 " [\n"
237 " \"txid\" (string) A transaction hash\n"
238 " ,...\n"
239 " ]\n"
240 "2. \"block hash\" (string, optional) If specified, looks for txid in the block with this hash\n"
241 "\nResult:\n"
242 "\"data\" (string) A string that is a serialized, hex-encoded data for the proof.\n"
243 );
244
245 set<uint256> setTxids;
246 uint256 oneTxid;
247 UniValue txids = params[0].get_array();
248 for (unsigned int idx = 0; idx < txids.size(); idx++) {
249 const UniValue& txid = txids[idx];
250 if (txid.get_str().length() != 64 || !IsHex(txid.get_str()))
251 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid txid ")+txid.get_str());
252 uint256 hash(uint256S(txid.get_str()));
253 if (setTxids.count(hash))
254 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated txid: ")+txid.get_str());
255 setTxids.insert(hash);
256 oneTxid = hash;
257 }
258
259 LOCK(cs_main);
260
261 CBlockIndex* pblockindex = NULL;
262
263 uint256 hashBlock;
264 if (params.size() > 1)
265 {
266 hashBlock = uint256S(params[1].get_str());
267 if (!mapBlockIndex.count(hashBlock))
268 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
269 pblockindex = mapBlockIndex[hashBlock];
270 } else {
271 CCoins coins;
272 if (pcoinsTip->GetCoins(oneTxid, coins) && coins.nHeight > 0 && coins.nHeight <= chainActive.Height())
273 pblockindex = chainActive[coins.nHeight];
274 }
275
276 if (pblockindex == NULL)
277 {
278 CTransaction tx;
279 if (!GetTransaction(oneTxid, tx, Params().GetConsensus(), hashBlock, false) || hashBlock.IsNull())
280 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block");
281 if (!mapBlockIndex.count(hashBlock))
282 throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt");
283 pblockindex = mapBlockIndex[hashBlock];
284 }
285
286 CBlock block;
287 if(!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
288 throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
289
290 unsigned int ntxFound = 0;
291 BOOST_FOREACH(const CTransaction&tx, block.vtx)
292 if (setTxids.count(tx.GetHash()))
293 ntxFound++;
294 if (ntxFound != setTxids.size())
295 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "(Not all) transactions not found in specified block");
296
297 CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS);
298 CMerkleBlock mb(block, setTxids);
299 ssMB << mb;
300 std::string strHex = HexStr(ssMB.begin(), ssMB.end());
301 return strHex;
302 }
303
verifytxoutproof(const UniValue & params,bool fHelp)304 UniValue verifytxoutproof(const UniValue& params, bool fHelp)
305 {
306 if (fHelp || params.size() != 1)
307 throw runtime_error(
308 "verifytxoutproof \"proof\"\n"
309 "\nVerifies that a proof points to a transaction in a block, returning the transaction it commits to\n"
310 "and throwing an RPC error if the block is not in our best chain\n"
311 "\nArguments:\n"
312 "1. \"proof\" (string, required) The hex-encoded proof generated by gettxoutproof\n"
313 "\nResult:\n"
314 "[\"txid\"] (array, strings) The txid(s) which the proof commits to, or empty array if the proof is invalid\n"
315 );
316
317 CDataStream ssMB(ParseHexV(params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS);
318 CMerkleBlock merkleBlock;
319 ssMB >> merkleBlock;
320
321 UniValue res(UniValue::VARR);
322
323 vector<uint256> vMatch;
324 vector<unsigned int> vIndex;
325 if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) != merkleBlock.header.hashMerkleRoot)
326 return res;
327
328 LOCK(cs_main);
329
330 if (!mapBlockIndex.count(merkleBlock.header.GetHash()) || !chainActive.Contains(mapBlockIndex[merkleBlock.header.GetHash()]))
331 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain");
332
333 BOOST_FOREACH(const uint256& hash, vMatch)
334 res.push_back(hash.GetHex());
335 return res;
336 }
337
createrawtransaction(const UniValue & params,bool fHelp)338 UniValue createrawtransaction(const UniValue& params, bool fHelp)
339 {
340 if (fHelp || params.size() < 2 || params.size() > 3)
341 throw runtime_error(
342 "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,\"data\":\"hex\",...} ( locktime )\n"
343 "\nCreate a transaction spending the given inputs and creating new outputs.\n"
344 "Outputs can be addresses or data.\n"
345 "Returns hex-encoded raw transaction.\n"
346 "Note that the transaction's inputs are not signed, and\n"
347 "it is not stored in the wallet or transmitted to the network.\n"
348
349 "\nArguments:\n"
350 "1. \"transactions\" (string, required) A json array of json objects\n"
351 " [\n"
352 " {\n"
353 " \"txid\":\"id\", (string, required) The transaction id\n"
354 " \"vout\":n (numeric, required) The output number\n"
355 " \"sequence\":n (numeric, optional) The sequence number\n"
356 " }\n"
357 " ,...\n"
358 " ]\n"
359 "2. \"outputs\" (string, required) a json object with outputs\n"
360 " {\n"
361 " \"address\": x.xxx (numeric or string, required) The key is the zetacoin address, the numeric value (can be string) is the " + CURRENCY_UNIT + " amount\n"
362 " \"data\": \"hex\", (string, required) The key is \"data\", the value is hex encoded data\n"
363 " ...\n"
364 " }\n"
365 "3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n"
366 "\nResult:\n"
367 "\"transaction\" (string) hex string of the transaction\n"
368
369 "\nExamples\n"
370 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":0.01}\"")
371 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"data\\\":\\\"00010203\\\"}\"")
372 + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\"")
373 + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"data\\\":\\\"00010203\\\"}\"")
374 );
375
376 RPCTypeCheck(params, boost::assign::list_of(UniValue::VARR)(UniValue::VOBJ)(UniValue::VNUM), true);
377 if (params[0].isNull() || params[1].isNull())
378 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, arguments 1 and 2 must be non-null");
379
380 UniValue inputs = params[0].get_array();
381 UniValue sendTo = params[1].get_obj();
382
383 CMutableTransaction rawTx;
384
385 if (params.size() > 2 && !params[2].isNull()) {
386 int64_t nLockTime = params[2].get_int64();
387 if (nLockTime < 0 || nLockTime > std::numeric_limits<uint32_t>::max())
388 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, locktime out of range");
389 rawTx.nLockTime = nLockTime;
390 }
391
392 for (unsigned int idx = 0; idx < inputs.size(); idx++) {
393 const UniValue& input = inputs[idx];
394 const UniValue& o = input.get_obj();
395
396 uint256 txid = ParseHashO(o, "txid");
397
398 const UniValue& vout_v = find_value(o, "vout");
399 if (!vout_v.isNum())
400 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");
401 int nOutput = vout_v.get_int();
402 if (nOutput < 0)
403 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
404
405 uint32_t nSequence = (rawTx.nLockTime ? std::numeric_limits<uint32_t>::max() - 1 : std::numeric_limits<uint32_t>::max());
406
407 // set the sequence number if passed in the parameters object
408 const UniValue& sequenceObj = find_value(o, "sequence");
409 if (sequenceObj.isNum()) {
410 int64_t seqNr64 = sequenceObj.get_int64();
411 if (seqNr64 < 0 || seqNr64 > std::numeric_limits<uint32_t>::max())
412 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, sequence number is out of range");
413 else
414 nSequence = (uint32_t)seqNr64;
415 }
416
417 CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence);
418
419 rawTx.vin.push_back(in);
420 }
421
422 set<CBitcoinAddress> setAddress;
423 vector<string> addrList = sendTo.getKeys();
424 BOOST_FOREACH(const string& name_, addrList) {
425
426 if (name_ == "data") {
427 std::vector<unsigned char> data = ParseHexV(sendTo[name_].getValStr(),"Data");
428
429 CTxOut out(0, CScript() << OP_RETURN << data);
430 rawTx.vout.push_back(out);
431 } else {
432 CBitcoinAddress address(name_);
433 if (!address.IsValid())
434 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Zetacoin address: ")+name_);
435
436 if (setAddress.count(address))
437 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+name_);
438 setAddress.insert(address);
439
440 CScript scriptPubKey = GetScriptForDestination(address.Get());
441 CAmount nAmount = AmountFromValue(sendTo[name_]);
442
443 CTxOut out(nAmount, scriptPubKey);
444 rawTx.vout.push_back(out);
445 }
446 }
447
448 return EncodeHexTx(rawTx);
449 }
450
decoderawtransaction(const UniValue & params,bool fHelp)451 UniValue decoderawtransaction(const UniValue& params, bool fHelp)
452 {
453 if (fHelp || params.size() != 1)
454 throw runtime_error(
455 "decoderawtransaction \"hexstring\"\n"
456 "\nReturn a JSON object representing the serialized, hex-encoded transaction.\n"
457
458 "\nArguments:\n"
459 "1. \"hex\" (string, required) The transaction hex string\n"
460
461 "\nResult:\n"
462 "{\n"
463 " \"txid\" : \"id\", (string) The transaction id\n"
464 " \"hash\" : \"id\", (string) The transaction hash (differs from txid for witness transactions)\n"
465 " \"size\" : n, (numeric) The transaction size\n"
466 " \"vsize\" : n, (numeric) The virtual transaction size (differs from size for witness transactions)\n"
467 " \"version\" : n, (numeric) The version\n"
468 " \"locktime\" : ttt, (numeric) The lock time\n"
469 " \"vin\" : [ (array of json objects)\n"
470 " {\n"
471 " \"txid\": \"id\", (string) The transaction id\n"
472 " \"vout\": n, (numeric) The output number\n"
473 " \"scriptSig\": { (json object) The script\n"
474 " \"asm\": \"asm\", (string) asm\n"
475 " \"hex\": \"hex\" (string) hex\n"
476 " },\n"
477 " \"txinwitness\": [\"hex\", ...] (array of string) hex-encoded witness data (if any)\n"
478 " \"sequence\": n (numeric) The script sequence number\n"
479 " }\n"
480 " ,...\n"
481 " ],\n"
482 " \"vout\" : [ (array of json objects)\n"
483 " {\n"
484 " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n"
485 " \"n\" : n, (numeric) index\n"
486 " \"scriptPubKey\" : { (json object)\n"
487 " \"asm\" : \"asm\", (string) the asm\n"
488 " \"hex\" : \"hex\", (string) the hex\n"
489 " \"reqSigs\" : n, (numeric) The required sigs\n"
490 " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
491 " \"addresses\" : [ (json array of string)\n"
492 " \"12tvKAXCxZjSmdNbao16dKXC8tRWfcF5oc\" (string) zetacoin address\n"
493 " ,...\n"
494 " ]\n"
495 " }\n"
496 " }\n"
497 " ,...\n"
498 " ],\n"
499 "}\n"
500
501 "\nExamples:\n"
502 + HelpExampleCli("decoderawtransaction", "\"hexstring\"")
503 + HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
504 );
505
506 LOCK(cs_main);
507 RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR));
508
509 CTransaction tx;
510
511 if (!DecodeHexTx(tx, params[0].get_str(), true))
512 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
513
514 UniValue result(UniValue::VOBJ);
515 TxToJSON(tx, uint256(), result);
516
517 return result;
518 }
519
decodescript(const UniValue & params,bool fHelp)520 UniValue decodescript(const UniValue& params, bool fHelp)
521 {
522 if (fHelp || params.size() != 1)
523 throw runtime_error(
524 "decodescript \"hex\"\n"
525 "\nDecode a hex-encoded script.\n"
526 "\nArguments:\n"
527 "1. \"hex\" (string) the hex encoded script\n"
528 "\nResult:\n"
529 "{\n"
530 " \"asm\":\"asm\", (string) Script public key\n"
531 " \"hex\":\"hex\", (string) hex encoded public key\n"
532 " \"type\":\"type\", (string) The output type\n"
533 " \"reqSigs\": n, (numeric) The required signatures\n"
534 " \"addresses\": [ (json array of string)\n"
535 " \"address\" (string) zetacoin address\n"
536 " ,...\n"
537 " ],\n"
538 " \"p2sh\",\"address\" (string) address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH).\n"
539 "}\n"
540 "\nExamples:\n"
541 + HelpExampleCli("decodescript", "\"hexstring\"")
542 + HelpExampleRpc("decodescript", "\"hexstring\"")
543 );
544
545 RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR));
546
547 UniValue r(UniValue::VOBJ);
548 CScript script;
549 if (params[0].get_str().size() > 0){
550 vector<unsigned char> scriptData(ParseHexV(params[0], "argument"));
551 script = CScript(scriptData.begin(), scriptData.end());
552 } else {
553 // Empty scripts are valid
554 }
555 ScriptPubKeyToJSON(script, r, false);
556
557 UniValue type;
558 type = find_value(r, "type");
559
560 if (type.isStr() && type.get_str() != "scripthash") {
561 // P2SH cannot be wrapped in a P2SH. If this script is already a P2SH,
562 // don't return the address for a P2SH of the P2SH.
563 r.push_back(Pair("p2sh", CBitcoinAddress(CScriptID(script)).ToString()));
564 }
565
566 return r;
567 }
568
569 /** Pushes a JSON object for script verification or signing errors to vErrorsRet. */
TxInErrorToJSON(const CTxIn & txin,UniValue & vErrorsRet,const std::string & strMessage)570 static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std::string& strMessage)
571 {
572 UniValue entry(UniValue::VOBJ);
573 entry.push_back(Pair("txid", txin.prevout.hash.ToString()));
574 entry.push_back(Pair("vout", (uint64_t)txin.prevout.n));
575 entry.push_back(Pair("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
576 entry.push_back(Pair("sequence", (uint64_t)txin.nSequence));
577 entry.push_back(Pair("error", strMessage));
578 vErrorsRet.push_back(entry);
579 }
580
signrawtransaction(const UniValue & params,bool fHelp)581 UniValue signrawtransaction(const UniValue& params, bool fHelp)
582 {
583 if (fHelp || params.size() < 1 || params.size() > 4)
584 throw runtime_error(
585 "signrawtransaction \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] [\"privatekey1\",...] sighashtype )\n"
586 "\nSign inputs for raw transaction (serialized, hex-encoded).\n"
587 "The second optional argument (may be null) is an array of previous transaction outputs that\n"
588 "this transaction depends on but may not yet be in the block chain.\n"
589 "The third optional argument (may be null) is an array of base58-encoded private\n"
590 "keys that, if given, will be the only keys used to sign the transaction.\n"
591 #ifdef ENABLE_WALLET
592 + HelpRequiringPassphrase() + "\n"
593 #endif
594
595 "\nArguments:\n"
596 "1. \"hexstring\" (string, required) The transaction hex string\n"
597 "2. \"prevtxs\" (string, optional) An json array of previous dependent transaction outputs\n"
598 " [ (json array of json objects, or 'null' if none provided)\n"
599 " {\n"
600 " \"txid\":\"id\", (string, required) The transaction id\n"
601 " \"vout\":n, (numeric, required) The output number\n"
602 " \"scriptPubKey\": \"hex\", (string, required) script key\n"
603 " \"redeemScript\": \"hex\", (string, required for P2SH or P2WSH) redeem script\n"
604 " \"amount\": value (numeric, required) The amount spent\n"
605 " }\n"
606 " ,...\n"
607 " ]\n"
608 "3. \"privatekeys\" (string, optional) A json array of base58-encoded private keys for signing\n"
609 " [ (json array of strings, or 'null' if none provided)\n"
610 " \"privatekey\" (string) private key in base58-encoding\n"
611 " ,...\n"
612 " ]\n"
613 "4. \"sighashtype\" (string, optional, default=ALL) The signature hash type. Must be one of\n"
614 " \"ALL\"\n"
615 " \"NONE\"\n"
616 " \"SINGLE\"\n"
617 " \"ALL|ANYONECANPAY\"\n"
618 " \"NONE|ANYONECANPAY\"\n"
619 " \"SINGLE|ANYONECANPAY\"\n"
620
621 "\nResult:\n"
622 "{\n"
623 " \"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n"
624 " \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n"
625 " \"errors\" : [ (json array of objects) Script verification errors (if there are any)\n"
626 " {\n"
627 " \"txid\" : \"hash\", (string) The hash of the referenced, previous transaction\n"
628 " \"vout\" : n, (numeric) The index of the output to spent and used as input\n"
629 " \"scriptSig\" : \"hex\", (string) The hex-encoded signature script\n"
630 " \"sequence\" : n, (numeric) Script sequence number\n"
631 " \"error\" : \"text\" (string) Verification or signing error related to the input\n"
632 " }\n"
633 " ,...\n"
634 " ]\n"
635 "}\n"
636
637 "\nExamples:\n"
638 + HelpExampleCli("signrawtransaction", "\"myhex\"")
639 + HelpExampleRpc("signrawtransaction", "\"myhex\"")
640 );
641
642 #ifdef ENABLE_WALLET
643 LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
644 #else
645 LOCK(cs_main);
646 #endif
647 RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VARR)(UniValue::VARR)(UniValue::VSTR), true);
648
649 vector<unsigned char> txData(ParseHexV(params[0], "argument 1"));
650 CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
651 vector<CMutableTransaction> txVariants;
652 while (!ssData.empty()) {
653 try {
654 CMutableTransaction tx;
655 ssData >> tx;
656 txVariants.push_back(tx);
657 }
658 catch (const std::exception&) {
659 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
660 }
661 }
662
663 if (txVariants.empty())
664 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transaction");
665
666 // mergedTx will end up with all the signatures; it
667 // starts as a clone of the rawtx:
668 CMutableTransaction mergedTx(txVariants[0]);
669
670 // Fetch previous transactions (inputs):
671 CCoinsView viewDummy;
672 CCoinsViewCache view(&viewDummy);
673 {
674 LOCK(mempool.cs);
675 CCoinsViewCache &viewChain = *pcoinsTip;
676 CCoinsViewMemPool viewMempool(&viewChain, mempool);
677 view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
678
679 BOOST_FOREACH(const CTxIn& txin, mergedTx.vin) {
680 const uint256& prevHash = txin.prevout.hash;
681 CCoins coins;
682 view.AccessCoins(prevHash); // this is certainly allowed to fail
683 }
684
685 view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
686 }
687
688 bool fGivenKeys = false;
689 CBasicKeyStore tempKeystore;
690 if (params.size() > 2 && !params[2].isNull()) {
691 fGivenKeys = true;
692 UniValue keys = params[2].get_array();
693 for (unsigned int idx = 0; idx < keys.size(); idx++) {
694 UniValue k = keys[idx];
695 CBitcoinSecret vchSecret;
696 bool fGood = vchSecret.SetString(k.get_str());
697 if (!fGood)
698 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
699 CKey key = vchSecret.GetKey();
700 if (!key.IsValid())
701 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
702 tempKeystore.AddKey(key);
703 }
704 }
705 #ifdef ENABLE_WALLET
706 else if (pwalletMain)
707 EnsureWalletIsUnlocked();
708 #endif
709
710 // Add previous txouts given in the RPC call:
711 if (params.size() > 1 && !params[1].isNull()) {
712 UniValue prevTxs = params[1].get_array();
713 for (unsigned int idx = 0; idx < prevTxs.size(); idx++) {
714 const UniValue& p = prevTxs[idx];
715 if (!p.isObject())
716 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}");
717
718 UniValue prevOut = p.get_obj();
719
720 RPCTypeCheckObj(prevOut,
721 {
722 {"txid", UniValueType(UniValue::VSTR)},
723 {"vout", UniValueType(UniValue::VNUM)},
724 {"scriptPubKey", UniValueType(UniValue::VSTR)},
725 });
726
727 uint256 txid = ParseHashO(prevOut, "txid");
728
729 int nOut = find_value(prevOut, "vout").get_int();
730 if (nOut < 0)
731 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout must be positive");
732
733 vector<unsigned char> pkData(ParseHexO(prevOut, "scriptPubKey"));
734 CScript scriptPubKey(pkData.begin(), pkData.end());
735
736 {
737 CCoinsModifier coins = view.ModifyCoins(txid);
738 if (coins->IsAvailable(nOut) && coins->vout[nOut].scriptPubKey != scriptPubKey) {
739 string err("Previous output scriptPubKey mismatch:\n");
740 err = err + ScriptToAsmStr(coins->vout[nOut].scriptPubKey) + "\nvs:\n"+
741 ScriptToAsmStr(scriptPubKey);
742 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err);
743 }
744 if ((unsigned int)nOut >= coins->vout.size())
745 coins->vout.resize(nOut+1);
746 coins->vout[nOut].scriptPubKey = scriptPubKey;
747 coins->vout[nOut].nValue = 0;
748 if (prevOut.exists("amount")) {
749 coins->vout[nOut].nValue = AmountFromValue(find_value(prevOut, "amount"));
750 }
751 }
752
753 // if redeemScript given and not using the local wallet (private keys
754 // given), add redeemScript to the tempKeystore so it can be signed:
755 if (fGivenKeys && (scriptPubKey.IsPayToScriptHash() || scriptPubKey.IsPayToWitnessScriptHash())) {
756 RPCTypeCheckObj(prevOut,
757 {
758 {"txid", UniValueType(UniValue::VSTR)},
759 {"vout", UniValueType(UniValue::VNUM)},
760 {"scriptPubKey", UniValueType(UniValue::VSTR)},
761 {"redeemScript", UniValueType(UniValue::VSTR)},
762 });
763 UniValue v = find_value(prevOut, "redeemScript");
764 if (!v.isNull()) {
765 vector<unsigned char> rsData(ParseHexV(v, "redeemScript"));
766 CScript redeemScript(rsData.begin(), rsData.end());
767 tempKeystore.AddCScript(redeemScript);
768 }
769 }
770 }
771 }
772
773 #ifdef ENABLE_WALLET
774 const CKeyStore& keystore = ((fGivenKeys || !pwalletMain) ? tempKeystore : *pwalletMain);
775 #else
776 const CKeyStore& keystore = tempKeystore;
777 #endif
778
779 int nHashType = SIGHASH_ALL;
780 if (params.size() > 3 && !params[3].isNull()) {
781 static map<string, int> mapSigHashValues =
782 boost::assign::map_list_of
783 (string("ALL"), int(SIGHASH_ALL))
784 (string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY))
785 (string("NONE"), int(SIGHASH_NONE))
786 (string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY))
787 (string("SINGLE"), int(SIGHASH_SINGLE))
788 (string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY))
789 ;
790 string strHashType = params[3].get_str();
791 if (mapSigHashValues.count(strHashType))
792 nHashType = mapSigHashValues[strHashType];
793 else
794 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param");
795 }
796
797 bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
798
799 // Script verification errors
800 UniValue vErrors(UniValue::VARR);
801
802 // Use CTransaction for the constant parts of the
803 // transaction to avoid rehashing.
804 const CTransaction txConst(mergedTx);
805 // Sign what we can:
806 for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
807 CTxIn& txin = mergedTx.vin[i];
808 const CCoins* coins = view.AccessCoins(txin.prevout.hash);
809 if (coins == NULL || !coins->IsAvailable(txin.prevout.n)) {
810 TxInErrorToJSON(txin, vErrors, "Input not found or already spent");
811 continue;
812 }
813 const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey;
814 const CAmount& amount = coins->vout[txin.prevout.n].nValue;
815
816 SignatureData sigdata;
817 // Only sign SIGHASH_SINGLE if there's a corresponding output:
818 if (!fHashSingle || (i < mergedTx.vout.size()))
819 ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mergedTx, i, amount, nHashType), prevPubKey, sigdata);
820
821 // ... and merge in other signatures:
822 BOOST_FOREACH(const CMutableTransaction& txv, txVariants) {
823 sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(txv, i));
824 }
825
826 UpdateTransaction(mergedTx, i, sigdata);
827
828 ScriptError serror = SCRIPT_ERR_OK;
829 if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx.wit.vtxinwit.size() > i ? &mergedTx.wit.vtxinwit[i].scriptWitness : NULL, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount), &serror)) {
830 TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror));
831 }
832 }
833 bool fComplete = vErrors.empty();
834
835 UniValue result(UniValue::VOBJ);
836 result.push_back(Pair("hex", EncodeHexTx(mergedTx)));
837 result.push_back(Pair("complete", fComplete));
838 if (!vErrors.empty()) {
839 result.push_back(Pair("errors", vErrors));
840 }
841
842 return result;
843 }
844
sendrawtransaction(const UniValue & params,bool fHelp)845 UniValue sendrawtransaction(const UniValue& params, bool fHelp)
846 {
847 if (fHelp || params.size() < 1 || params.size() > 2)
848 throw runtime_error(
849 "sendrawtransaction \"hexstring\" ( allowhighfees )\n"
850 "\nSubmits raw transaction (serialized, hex-encoded) to local node and network.\n"
851 "\nAlso see createrawtransaction and signrawtransaction calls.\n"
852 "\nArguments:\n"
853 "1. \"hexstring\" (string, required) The hex string of the raw transaction)\n"
854 "2. allowhighfees (boolean, optional, default=false) Allow high fees\n"
855 "\nResult:\n"
856 "\"hex\" (string) The transaction hash in hex\n"
857 "\nExamples:\n"
858 "\nCreate a transaction\n"
859 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") +
860 "Sign the transaction, and get back the hex\n"
861 + HelpExampleCli("signrawtransaction", "\"myhex\"") +
862 "\nSend the transaction (signed hex)\n"
863 + HelpExampleCli("sendrawtransaction", "\"signedhex\"") +
864 "\nAs a json rpc call\n"
865 + HelpExampleRpc("sendrawtransaction", "\"signedhex\"")
866 );
867
868 LOCK(cs_main);
869 RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VBOOL));
870
871 // parse hex string from parameter
872 CTransaction tx;
873 if (!DecodeHexTx(tx, params[0].get_str()))
874 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
875 uint256 hashTx = tx.GetHash();
876
877 CAmount nMaxRawTxFee = maxTxFee;
878 if (params.size() > 1 && params[1].get_bool())
879 nMaxRawTxFee = 0;
880
881 CCoinsViewCache &view = *pcoinsTip;
882 const CCoins* existingCoins = view.AccessCoins(hashTx);
883 bool fHaveMempool = mempool.exists(hashTx);
884 bool fHaveChain = existingCoins && existingCoins->nHeight < 1000000000;
885 if (!fHaveMempool && !fHaveChain) {
886 // push to local node and sync with wallets
887 CValidationState state;
888 bool fMissingInputs;
889 if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, false, nMaxRawTxFee)) {
890 if (state.IsInvalid()) {
891 throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
892 } else {
893 if (fMissingInputs) {
894 throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs");
895 }
896 throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason());
897 }
898 }
899 } else if (fHaveChain) {
900 throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain");
901 }
902 RelayTransaction(tx);
903
904 return hashTx.GetHex();
905 }
906
907 static const CRPCCommand commands[] =
908 { // category name actor (function) okSafeMode
909 // --------------------- ------------------------ ----------------------- ----------
910 { "rawtransactions", "getrawtransaction", &getrawtransaction, true },
911 { "rawtransactions", "createrawtransaction", &createrawtransaction, true },
912 { "rawtransactions", "decoderawtransaction", &decoderawtransaction, true },
913 { "rawtransactions", "decodescript", &decodescript, true },
914 { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false },
915 { "rawtransactions", "signrawtransaction", &signrawtransaction, false }, /* uses wallet if enabled */
916
917 { "blockchain", "gettxoutproof", &gettxoutproof, true },
918 { "blockchain", "verifytxoutproof", &verifytxoutproof, true },
919 };
920
RegisterRawTransactionRPCCommands(CRPCTable & tableRPC)921 void RegisterRawTransactionRPCCommands(CRPCTable &tableRPC)
922 {
923 for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
924 tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
925 }
926