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