]> Git Repo - VerusCoin.git/blob - src/rpc/rawtransaction.cpp
fix finalization on accepted notarization
[VerusCoin.git] / src / rpc / rawtransaction.cpp
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 "consensus/upgrades.h"
7 #include "consensus/validation.h"
8 #include "core_io.h"
9 #include "init.h"
10 #include "deprecation.h"
11 #include "key_io.h"
12 #include "keystore.h"
13 #include "main.h"
14 #include "merkleblock.h"
15 #include "net.h"
16 #include "primitives/transaction.h"
17 #include "rpc/server.h"
18 #include "script/script.h"
19 #include "script/script_error.h"
20 #include "script/sign.h"
21 #include "script/standard.h"
22 #include "uint256.h"
23 #ifdef ENABLE_WALLET
24 #include "wallet/wallet.h"
25 #endif
26
27 #include "komodo_defs.h"
28
29 #include <stdint.h>
30
31 #include <boost/assign/list_of.hpp>
32
33 #include <univalue.h>
34
35 using namespace std;
36
37 extern char ASSETCHAINS_SYMBOL[];
38
39 void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex)
40 {
41     txnouttype type;
42     vector<CTxDestination> addresses;
43     int nRequired;
44
45     out.push_back(Pair("asm", ScriptToAsmStr(scriptPubKey)));
46     if (fIncludeHex)
47         out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
48
49     if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired))
50     {
51         out.push_back(Pair("type", GetTxnOutputType(type)));
52         return;
53     }
54
55     out.push_back(Pair("reqSigs", nRequired));
56     out.push_back(Pair("type", GetTxnOutputType(type)));
57
58     UniValue a(UniValue::VARR);
59     for (const CTxDestination& addr : addresses) {
60         a.push_back(EncodeDestination(addr));
61     }
62     out.push_back(Pair("addresses", a));
63 }
64
65 UniValue TxJoinSplitToJSON(const CTransaction& tx) {
66     bool useGroth = tx.fOverwintered && tx.nVersion >= SAPLING_TX_VERSION;
67     UniValue vjoinsplit(UniValue::VARR);
68     for (unsigned int i = 0; i < tx.vjoinsplit.size(); i++) {
69         const JSDescription& jsdescription = tx.vjoinsplit[i];
70         UniValue joinsplit(UniValue::VOBJ);
71
72         joinsplit.push_back(Pair("vpub_old", ValueFromAmount(jsdescription.vpub_old)));
73         joinsplit.push_back(Pair("vpub_oldZat", jsdescription.vpub_old));
74         joinsplit.push_back(Pair("vpub_new", ValueFromAmount(jsdescription.vpub_new)));
75         joinsplit.push_back(Pair("vpub_newZat", jsdescription.vpub_new));
76
77         joinsplit.push_back(Pair("anchor", jsdescription.anchor.GetHex()));
78
79         {
80             UniValue nullifiers(UniValue::VARR);
81             BOOST_FOREACH(const uint256 nf, jsdescription.nullifiers) {
82                 nullifiers.push_back(nf.GetHex());
83             }
84             joinsplit.push_back(Pair("nullifiers", nullifiers));
85         }
86
87         {
88             UniValue commitments(UniValue::VARR);
89             BOOST_FOREACH(const uint256 commitment, jsdescription.commitments) {
90                 commitments.push_back(commitment.GetHex());
91             }
92             joinsplit.push_back(Pair("commitments", commitments));
93         }
94
95         joinsplit.push_back(Pair("onetimePubKey", jsdescription.ephemeralKey.GetHex()));
96         joinsplit.push_back(Pair("randomSeed", jsdescription.randomSeed.GetHex()));
97
98         {
99             UniValue macs(UniValue::VARR);
100             BOOST_FOREACH(const uint256 mac, jsdescription.macs) {
101                 macs.push_back(mac.GetHex());
102             }
103             joinsplit.push_back(Pair("macs", macs));
104         }
105
106         CDataStream ssProof(SER_NETWORK, PROTOCOL_VERSION);
107         auto ps = SproutProofSerializer<CDataStream>(ssProof, useGroth);
108         boost::apply_visitor(ps, jsdescription.proof);
109         joinsplit.push_back(Pair("proof", HexStr(ssProof.begin(), ssProof.end())));
110
111         {
112             UniValue ciphertexts(UniValue::VARR);
113             for (const ZCNoteEncryption::Ciphertext ct : jsdescription.ciphertexts) {
114                 ciphertexts.push_back(HexStr(ct.begin(), ct.end()));
115             }
116             joinsplit.push_back(Pair("ciphertexts", ciphertexts));
117         }
118
119         vjoinsplit.push_back(joinsplit);
120     }
121     return vjoinsplit;
122 }
123
124 uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight);
125
126 UniValue TxShieldedSpendsToJSON(const CTransaction& tx) {
127     UniValue vdesc(UniValue::VARR);
128     for (const SpendDescription& spendDesc : tx.vShieldedSpend) {
129         UniValue obj(UniValue::VOBJ);
130         obj.push_back(Pair("cv", spendDesc.cv.GetHex()));
131         obj.push_back(Pair("anchor", spendDesc.anchor.GetHex()));
132         obj.push_back(Pair("nullifier", spendDesc.nullifier.GetHex()));
133         obj.push_back(Pair("rk", spendDesc.rk.GetHex()));
134         obj.push_back(Pair("proof", HexStr(spendDesc.zkproof.begin(), spendDesc.zkproof.end())));
135         obj.push_back(Pair("spendAuthSig", HexStr(spendDesc.spendAuthSig.begin(), spendDesc.spendAuthSig.end())));
136         vdesc.push_back(obj);
137     }
138     return vdesc;
139 }
140
141 UniValue TxShieldedOutputsToJSON(const CTransaction& tx) {
142     UniValue vdesc(UniValue::VARR);
143     for (const OutputDescription& outputDesc : tx.vShieldedOutput) {
144         UniValue obj(UniValue::VOBJ);
145         obj.push_back(Pair("cv", outputDesc.cv.GetHex()));
146         obj.push_back(Pair("cmu", outputDesc.cm.GetHex()));
147         obj.push_back(Pair("ephemeralKey", outputDesc.ephemeralKey.GetHex()));
148         obj.push_back(Pair("encCiphertext", HexStr(outputDesc.encCiphertext.begin(), outputDesc.encCiphertext.end())));
149         obj.push_back(Pair("outCiphertext", HexStr(outputDesc.outCiphertext.begin(), outputDesc.outCiphertext.end())));
150         obj.push_back(Pair("proof", HexStr(outputDesc.zkproof.begin(), outputDesc.zkproof.end())));
151         vdesc.push_back(obj);
152     }
153     return vdesc;
154 }
155
156 int32_t myIsutxo_spent(uint256 &spenttxid,uint256 txid,int32_t vout)
157 {
158     CSpentIndexValue spentInfo; CSpentIndexKey spentKey(txid,vout);
159     if ( GetSpentIndex(spentKey,spentInfo) )
160     {
161         spenttxid = spentInfo.txid;
162         return((int32_t)spentInfo.inputIndex);
163         // out.push_back(Pair("spentHeight", spentInfo.blockHeight));
164     }
165     memset(&spenttxid,0,sizeof(spenttxid));
166     return(-1);
167 }
168
169 void TxToJSONExpanded(const CTransaction& tx, const uint256 hashBlock, UniValue& entry, int nHeight = 0, int nConfirmations = 0, int nBlockTime = 0)
170 {
171     uint256 txid = tx.GetHash();
172     entry.push_back(Pair("txid", txid.GetHex()));
173     entry.push_back(Pair("overwintered", tx.fOverwintered));
174     entry.push_back(Pair("version", tx.nVersion));
175     if (tx.fOverwintered) {
176         entry.push_back(Pair("versiongroupid", HexInt(tx.nVersionGroupId)));
177     }
178     entry.push_back(Pair("locktime", (int64_t)tx.nLockTime));
179     if (tx.fOverwintered) {
180         entry.push_back(Pair("expiryheight", (int64_t)tx.nExpiryHeight));
181     }
182     UniValue vin(UniValue::VARR);
183     BOOST_FOREACH(const CTxIn& txin, tx.vin) {
184         UniValue in(UniValue::VOBJ);
185         if (tx.IsCoinBase())
186             in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
187         else if (tx.IsCoinImport()) {
188             in.push_back(Pair("is_import", "1"));
189         }
190         else {
191             in.push_back(Pair("txid", txin.prevout.hash.GetHex()));
192             in.push_back(Pair("vout", (int64_t)txin.prevout.n));
193             {
194                 uint256 hash; CTransaction tx; CTxDestination address;
195                 if (GetTransaction(txin.prevout.hash,tx,hash,false))
196                 {
197                     if (ExtractDestination(tx.vout[txin.prevout.n].scriptPubKey, address))
198                         in.push_back(Pair("address", CBitcoinAddress(address).ToString()));
199                 }
200             }
201             UniValue o(UniValue::VOBJ);
202             o.push_back(Pair("asm", ScriptToAsmStr(txin.scriptSig, true)));
203             o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
204             in.push_back(Pair("scriptSig", o));
205
206             // Add address and value info if spentindex enabled
207             CSpentIndexValue spentInfo;
208             CSpentIndexKey spentKey(txin.prevout.hash, txin.prevout.n);
209             if (GetSpentIndex(spentKey, spentInfo)) {
210                 in.push_back(Pair("value", ValueFromAmount(spentInfo.satoshis)));
211                 in.push_back(Pair("valueSat", spentInfo.satoshis));
212                 if (spentInfo.addressType == 1) {
213                     in.push_back(Pair("address", CBitcoinAddress(CKeyID(spentInfo.addressHash)).ToString()));
214                 }
215                 else if (spentInfo.addressType == 2)  {
216                     in.push_back(Pair("address", CBitcoinAddress(CScriptID(spentInfo.addressHash)).ToString()));
217                 }
218             }
219         }
220         in.push_back(Pair("sequence", (int64_t)txin.nSequence));
221         vin.push_back(in);
222     }
223     entry.push_back(Pair("vin", vin));
224     BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
225     CBlockIndex *tipindex,*pindex = it->second;
226     uint64_t interest;
227     UniValue vout(UniValue::VARR);
228     for (unsigned int i = 0; i < tx.vout.size(); i++)
229     {
230         const CTxOut& txout = tx.vout[i];
231         UniValue out(UniValue::VOBJ);
232         out.push_back(Pair("value", ValueFromAmount(txout.nValue)));
233         if ( ASSETCHAINS_SYMBOL[0] == 0 && pindex != 0 && tx.nLockTime >= 500000000 && (tipindex= chainActive.LastTip()) != 0 )
234         {
235             int64_t interest; int32_t txheight; uint32_t locktime;
236             interest = komodo_accrued_interest(&txheight,&locktime,tx.GetHash(),i,0,txout.nValue,(int32_t)tipindex->GetHeight());
237             out.push_back(Pair("interest", ValueFromAmount(interest)));
238         }
239         out.push_back(Pair("valueSat", txout.nValue)); // [+] Decker
240         out.push_back(Pair("n", (int64_t)i));
241         UniValue o(UniValue::VOBJ);
242         ScriptPubKeyToJSON(txout.scriptPubKey, o, true);
243         out.push_back(Pair("scriptPubKey", o));
244
245         // Add spent information if spentindex is enabled
246         CSpentIndexValue spentInfo;
247         CSpentIndexKey spentKey(txid, i);
248         if (GetSpentIndex(spentKey, spentInfo)) {
249             out.push_back(Pair("spentTxId", spentInfo.txid.GetHex()));
250             out.push_back(Pair("spentIndex", (int)spentInfo.inputIndex));
251             out.push_back(Pair("spentHeight", spentInfo.blockHeight));
252         }
253
254         vout.push_back(out);
255     }
256     entry.push_back(Pair("vout", vout));
257
258     UniValue vjoinsplit = TxJoinSplitToJSON(tx);
259     entry.push_back(Pair("vjoinsplit", vjoinsplit));
260
261     if (tx.fOverwintered && tx.nVersion >= SAPLING_TX_VERSION) {
262         entry.push_back(Pair("valueBalance", ValueFromAmount(tx.valueBalance)));
263         UniValue vspenddesc = TxShieldedSpendsToJSON(tx);
264         entry.push_back(Pair("vShieldedSpend", vspenddesc));
265         UniValue voutputdesc = TxShieldedOutputsToJSON(tx);
266         entry.push_back(Pair("vShieldedOutput", voutputdesc));
267         if (!(vspenddesc.empty() && voutputdesc.empty())) {
268             entry.push_back(Pair("bindingSig", HexStr(tx.bindingSig.begin(), tx.bindingSig.end())));
269         }
270     }
271
272     if (!hashBlock.IsNull()) {
273         entry.push_back(Pair("blockhash", hashBlock.GetHex()));
274
275         if (nConfirmations > 0) {
276             entry.push_back(Pair("height", nHeight));
277             entry.push_back(Pair("confirmations", nConfirmations));
278             entry.push_back(Pair("time", nBlockTime));
279             entry.push_back(Pair("blocktime", nBlockTime));
280         } else {
281             entry.push_back(Pair("height", -1));
282             entry.push_back(Pair("confirmations", 0));
283         }
284     }
285
286 }
287
288 void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
289 {
290     entry.push_back(Pair("txid", tx.GetHash().GetHex()));
291     entry.push_back(Pair("overwintered", tx.fOverwintered));
292     entry.push_back(Pair("version", tx.nVersion));
293     if (tx.fOverwintered) {
294         entry.push_back(Pair("versiongroupid", HexInt(tx.nVersionGroupId)));
295     }
296     entry.push_back(Pair("locktime", (int64_t)tx.nLockTime));
297     if (tx.fOverwintered) {
298         entry.push_back(Pair("expiryheight", (int64_t)tx.nExpiryHeight));
299     }
300     UniValue vin(UniValue::VARR);
301     BOOST_FOREACH(const CTxIn& txin, tx.vin) {
302         UniValue in(UniValue::VOBJ);
303         if (tx.IsCoinBase())
304             in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
305         else {
306             in.push_back(Pair("txid", txin.prevout.hash.GetHex()));
307             in.push_back(Pair("vout", (int64_t)txin.prevout.n));
308             UniValue o(UniValue::VOBJ);
309             o.push_back(Pair("asm", ScriptToAsmStr(txin.scriptSig, true)));
310             o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
311             in.push_back(Pair("scriptSig", o));
312         }
313         in.push_back(Pair("sequence", (int64_t)txin.nSequence));
314         vin.push_back(in);
315     }
316     entry.push_back(Pair("vin", vin));
317     UniValue vout(UniValue::VARR);
318     BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
319     CBlockIndex *tipindex,*pindex = it->second;
320     uint64_t interest;
321     for (unsigned int i = 0; i < tx.vout.size(); i++) {
322         const CTxOut& txout = tx.vout[i];
323         UniValue out(UniValue::VOBJ);
324         out.push_back(Pair("value", ValueFromAmount(txout.nValue)));
325         if ( ASSETCHAINS_SYMBOL[0] == 0 && pindex != 0 && tx.nLockTime >= 500000000 && (tipindex= chainActive.LastTip()) != 0 )
326         {
327             int64_t interest; int32_t txheight; uint32_t locktime;
328             interest = komodo_accrued_interest(&txheight,&locktime,tx.GetHash(),i,0,txout.nValue,(int32_t)tipindex->GetHeight());
329             out.push_back(Pair("interest", ValueFromAmount(interest)));
330         }        
331         out.push_back(Pair("valueZat", txout.nValue));
332         out.push_back(Pair("n", (int64_t)i));
333         UniValue o(UniValue::VOBJ);
334         ScriptPubKeyToJSON(txout.scriptPubKey, o, true);
335         out.push_back(Pair("scriptPubKey", o));
336         vout.push_back(out);
337     }
338     entry.push_back(Pair("vout", vout));
339
340     UniValue vjoinsplit = TxJoinSplitToJSON(tx);
341     entry.push_back(Pair("vjoinsplit", vjoinsplit));
342
343     if (tx.fOverwintered && tx.nVersion >= SAPLING_TX_VERSION) {
344         entry.push_back(Pair("valueBalance", ValueFromAmount(tx.valueBalance)));
345         UniValue vspenddesc = TxShieldedSpendsToJSON(tx);
346         entry.push_back(Pair("vShieldedSpend", vspenddesc));
347         UniValue voutputdesc = TxShieldedOutputsToJSON(tx);
348         entry.push_back(Pair("vShieldedOutput", voutputdesc));
349         if (!(vspenddesc.empty() && voutputdesc.empty())) {
350             entry.push_back(Pair("bindingSig", HexStr(tx.bindingSig.begin(), tx.bindingSig.end())));
351         }
352     }
353
354     if (!hashBlock.IsNull()) {
355         entry.push_back(Pair("blockhash", hashBlock.GetHex()));
356         BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
357         if (mi != mapBlockIndex.end() && (*mi).second) {
358             CBlockIndex* pindex = (*mi).second;
359             if (chainActive.Contains(pindex)) {
360                 entry.push_back(Pair("confirmations", 1 + chainActive.Height() - pindex->GetHeight()));
361                 entry.push_back(Pair("time", pindex->GetBlockTime()));
362                 entry.push_back(Pair("blocktime", pindex->GetBlockTime()));
363             }
364             else
365                 entry.push_back(Pair("confirmations", 0));
366         }
367     }
368 }
369
370 UniValue getrawtransaction(const UniValue& params, bool fHelp)
371 {
372     if (fHelp || params.size() < 1 || params.size() > 2)
373         throw runtime_error(
374             "getrawtransaction \"txid\" ( verbose )\n"
375             "\nNOTE: By default this function only works sometimes. This is when the tx is in the mempool\n"
376             "or there is an unspent output in the utxo for this transaction. To make it always work,\n"
377             "you need to maintain a transaction index, using the -txindex command line option.\n"
378             "\nReturn the raw transaction data.\n"
379             "\nIf verbose=0, returns a string that is serialized, hex-encoded data for 'txid'.\n"
380             "If verbose is non-zero, returns an Object with information about 'txid'.\n"
381
382             "\nArguments:\n"
383             "1. \"txid\"      (string, required) The transaction id\n"
384             "2. verbose       (numeric, optional, default=0) If 0, return a string, other return a json object\n"
385
386             "\nResult (if verbose is not set or set to 0):\n"
387             "\"data\"      (string) The serialized, hex-encoded data for 'txid'\n"
388
389             "\nResult (if verbose > 0):\n"
390             "{\n"
391             "  \"hex\" : \"data\",       (string) The serialized, hex-encoded data for 'txid'\n"
392             "  \"txid\" : \"id\",        (string) The transaction id (same as provided)\n"
393             "  \"version\" : n,          (numeric) The version\n"
394             "  \"locktime\" : ttt,       (numeric) The lock time\n"
395             "  \"expiryheight\" : ttt,   (numeric, optional) The block height after which the transaction expires\n"
396             "  \"vin\" : [               (array of json objects)\n"
397             "     {\n"
398             "       \"txid\": \"id\",    (string) The transaction id\n"
399             "       \"vout\": n,         (numeric) \n"
400             "       \"scriptSig\": {     (json object) The script\n"
401             "         \"asm\": \"asm\",  (string) asm\n"
402             "         \"hex\": \"hex\"   (string) hex\n"
403             "       },\n"
404             "       \"sequence\": n      (numeric) The script sequence number\n"
405             "     }\n"
406             "     ,...\n"
407             "  ],\n"
408             "  \"vout\" : [              (array of json objects)\n"
409             "     {\n"
410             "       \"value\" : x.xxx,            (numeric) The value in " + CURRENCY_UNIT + "\n"
411             "       \"n\" : n,                    (numeric) index\n"
412             "       \"scriptPubKey\" : {          (json object)\n"
413             "         \"asm\" : \"asm\",          (string) the asm\n"
414             "         \"hex\" : \"hex\",          (string) the hex\n"
415             "         \"reqSigs\" : n,            (numeric) The required sigs\n"
416             "         \"type\" : \"pubkeyhash\",  (string) The type, eg 'pubkeyhash'\n"
417             "         \"addresses\" : [           (json array of string)\n"
418             "           \"komodoaddress\"          (string) Komodo address\n"
419             "           ,...\n"
420             "         ]\n"
421             "       }\n"
422             "     }\n"
423             "     ,...\n"
424             "  ],\n"
425             "  \"vjoinsplit\" : [        (array of json objects, only for version >= 2)\n"
426             "     {\n"
427             "       \"vpub_old\" : x.xxx,         (numeric) public input value in KMD\n"
428             "       \"vpub_new\" : x.xxx,         (numeric) public output value in KMD\n"
429             "       \"anchor\" : \"hex\",         (string) the anchor\n"
430             "       \"nullifiers\" : [            (json array of string)\n"
431             "         \"hex\"                     (string) input note nullifier\n"
432             "         ,...\n"
433             "       ],\n"
434             "       \"commitments\" : [           (json array of string)\n"
435             "         \"hex\"                     (string) output note commitment\n"
436             "         ,...\n"
437             "       ],\n"
438             "       \"onetimePubKey\" : \"hex\",  (string) the onetime public key used to encrypt the ciphertexts\n"
439             "       \"randomSeed\" : \"hex\",     (string) the random seed\n"
440             "       \"macs\" : [                  (json array of string)\n"
441             "         \"hex\"                     (string) input note MAC\n"
442             "         ,...\n"
443             "       ],\n"
444             "       \"proof\" : \"hex\",          (string) the zero-knowledge proof\n"
445             "       \"ciphertexts\" : [           (json array of string)\n"
446             "         \"hex\"                     (string) output note ciphertext\n"
447             "         ,...\n"
448             "       ]\n"
449             "     }\n"
450             "     ,...\n"
451             "  ],\n"
452             "  \"blockhash\" : \"hash\",   (string) the block hash\n"
453             "  \"confirmations\" : n,      (numeric) The confirmations\n"
454             "  \"time\" : ttt,             (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT)\n"
455             "  \"blocktime\" : ttt         (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
456             "}\n"
457
458             "\nExamples:\n"
459             + HelpExampleCli("getrawtransaction", "\"mytxid\"")
460             + HelpExampleCli("getrawtransaction", "\"mytxid\" 1")
461             + HelpExampleRpc("getrawtransaction", "\"mytxid\", 1")
462         );
463
464
465     uint256 hash = ParseHashV(params[0], "parameter 1");
466
467     bool fVerbose = false;
468     if (params.size() > 1)
469         fVerbose = (params[1].get_int() != 0);
470
471     CTransaction tx;
472     uint256 hashBlock;
473     int nHeight = 0;
474     int nConfirmations = 0;
475     int nBlockTime = 0;
476
477     {
478         LOCK(cs_main);
479         if (!GetTransaction(hash, tx, hashBlock, true))
480             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction");
481
482         BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
483         if (mi != mapBlockIndex.end() && (*mi).second) {
484             CBlockIndex* pindex = (*mi).second;
485             if (chainActive.Contains(pindex)) {
486                 nHeight = pindex->GetHeight();
487                 nConfirmations = 1 + chainActive.Height() - pindex->GetHeight();
488                 nBlockTime = pindex->GetBlockTime();
489             } else {
490                 nHeight = -1;
491                 nConfirmations = 0;
492                 nBlockTime = pindex->GetBlockTime();
493             }
494         }
495     }
496
497     string strHex = EncodeHexTx(tx);
498
499     if (!fVerbose)
500         return strHex;
501
502     UniValue result(UniValue::VOBJ);
503     result.push_back(Pair("hex", strHex));
504     TxToJSONExpanded(tx, hashBlock, result, nHeight, nConfirmations, nBlockTime);
505     return result;
506 }
507
508 int32_t gettxout_scriptPubKey(uint8_t *scriptPubKey,int32_t maxsize,uint256 txid,int32_t n)
509 {
510     int32_t i,m; uint8_t *ptr;
511     LOCK(cs_main);
512     /*CCoins coins;
513      for (iter=0; iter<2; iter++)
514      {
515      if ( iter == 0 )
516      {
517      LOCK(mempool.cs);
518      CCoinsViewMemPool view(pcoinsTip,mempool);
519      if ( view.GetCoins(txid,coins) == 0 )
520      {
521      //fprintf(stderr,"cant get view\n");
522      continue;
523      }
524      mempool.pruneSpent(txid, coins); // TODO: this should be done by the CCoinsViewMemPool
525      }
526      else if ( pcoinsTip->GetCoins(txid,coins) == 0 )
527      {
528      //fprintf(stderr,"cant get pcoinsTip->GetCoins\n");
529      continue;
530      }
531      if ( n < 0 || (unsigned int)n >= coins.vout.size() || coins.vout[n].IsNull() )
532      {
533      fprintf(stderr,"iter.%d n.%d vs voutsize.%d\n",iter,n,(int32_t)coins.vout.size());
534      continue;
535      }
536      ptr = (uint8_t *)coins.vout[n].scriptPubKey.data();
537      m = coins.vout[n].scriptPubKey.size();
538      for (i=0; i<maxsize&&i<m; i++)
539      scriptPubKey[i] = ptr[i];
540      return(i);
541      }*/
542     CTransaction tx;
543     uint256 hashBlock;
544     if ( GetTransaction(txid,tx,hashBlock,false) == 0 )
545         return(-1);
546     else if ( n <= tx.vout.size() ) // vout.size() seems off by 1
547     {
548         ptr = (uint8_t *)&tx.vout[n].scriptPubKey[0];
549         m = tx.vout[n].scriptPubKey.size();
550         for (i=0; i<maxsize&&i<m; i++)
551             scriptPubKey[i] = ptr[i];
552         //fprintf(stderr,"got scriptPubKey via rawtransaction\n");
553         return(i);
554     }
555     return(-1);
556 }
557
558 UniValue gettxoutproof(const UniValue& params, bool fHelp)
559 {
560     if (fHelp || (params.size() != 1 && params.size() != 2))
561         throw runtime_error(
562             "gettxoutproof [\"txid\",...] ( blockhash )\n"
563             "\nReturns a hex-encoded proof that \"txid\" was included in a block.\n"
564             "\nNOTE: By default this function only works sometimes. This is when there is an\n"
565             "unspent output in the utxo for this transaction. To make it always work,\n"
566             "you need to maintain a transaction index, using the -txindex command line option or\n"
567             "specify the block in which the transaction is included in manually (by blockhash).\n"
568             "\nReturn the raw transaction data.\n"
569             "\nArguments:\n"
570             "1. \"txids\"       (string) A json array of txids to filter\n"
571             "    [\n"
572             "      \"txid\"     (string) A transaction hash\n"
573             "      ,...\n"
574             "    ]\n"
575             "2. \"block hash\"  (string, optional) If specified, looks for txid in the block with this hash\n"
576             "\nResult:\n"
577             "\"data\"           (string) A string that is a serialized, hex-encoded data for the proof.\n"
578         );
579
580     set<uint256> setTxids;
581     uint256 oneTxid;
582     UniValue txids = params[0].get_array();
583     for (size_t idx = 0; idx < txids.size(); idx++) {
584         const UniValue& txid = txids[idx];
585         if (txid.get_str().length() != 64 || !IsHex(txid.get_str()))
586             throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid txid ")+txid.get_str());
587         uint256 hash(uint256S(txid.get_str()));
588         if (setTxids.count(hash))
589             throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated txid: ")+txid.get_str());
590        setTxids.insert(hash);
591        oneTxid = hash;
592     }
593
594     LOCK(cs_main);
595
596     CBlockIndex* pblockindex = NULL;
597
598     uint256 hashBlock;
599     if (params.size() > 1)
600     {
601         hashBlock = uint256S(params[1].get_str());
602         if (!mapBlockIndex.count(hashBlock))
603             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
604         pblockindex = mapBlockIndex[hashBlock];
605     } else {
606         CCoins coins;
607         if (pcoinsTip->GetCoins(oneTxid, coins) && coins.nHeight > 0 && coins.nHeight <= chainActive.Height())
608             pblockindex = chainActive[coins.nHeight];
609     }
610
611     if (pblockindex == NULL)
612     {
613         CTransaction tx;
614         if (!GetTransaction(oneTxid, tx, hashBlock, false) || hashBlock.IsNull())
615             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block");
616         if (!mapBlockIndex.count(hashBlock))
617             throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt");
618         pblockindex = mapBlockIndex[hashBlock];
619     }
620
621     CBlock block;
622     if(!ReadBlockFromDisk(block, pblockindex,1))
623         throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
624
625     unsigned int ntxFound = 0;
626     BOOST_FOREACH(const CTransaction&tx, block.vtx)
627         if (setTxids.count(tx.GetHash()))
628             ntxFound++;
629     if (ntxFound != setTxids.size())
630         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "(Not all) transactions not found in specified block");
631
632     CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION);
633     CMerkleBlock mb(block, setTxids);
634     ssMB << mb;
635     std::string strHex = HexStr(ssMB.begin(), ssMB.end());
636     return strHex;
637 }
638
639 UniValue verifytxoutproof(const UniValue& params, bool fHelp)
640 {
641     if (fHelp || params.size() != 1)
642         throw runtime_error(
643             "verifytxoutproof \"proof\"\n"
644             "\nVerifies that a proof points to a transaction in a block, returning the transaction it commits to\n"
645             "and throwing an RPC error if the block is not in our best chain\n"
646             "\nArguments:\n"
647             "1. \"proof\"    (string, required) The hex-encoded proof generated by gettxoutproof\n"
648             "\nResult:\n"
649             "[\"txid\"]      (array, strings) The txid(s) which the proof commits to, or empty array if the proof is invalid\n"
650         );
651
652     CDataStream ssMB(ParseHexV(params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION);
653     CMerkleBlock merkleBlock;
654     ssMB >> merkleBlock;
655
656     UniValue res(UniValue::VARR);
657
658     vector<uint256> vMatch;
659     if (merkleBlock.txn.ExtractMatches(vMatch) != merkleBlock.header.hashMerkleRoot)
660         return res;
661
662     LOCK(cs_main);
663     uint256 idx = merkleBlock.header.GetHash();
664     if (!mapBlockIndex.count(merkleBlock.header.GetHash()) || (mapBlockIndex.count(idx) && !chainActive.Contains(mapBlockIndex[idx])))
665         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain");
666
667     BOOST_FOREACH(const uint256& hash, vMatch)
668         res.push_back(hash.GetHex());
669     return res;
670 }
671
672 UniValue createrawtransaction(const UniValue& params, bool fHelp)
673 {
674     if (fHelp || params.size() < 2 || params.size() > 4)
675         throw runtime_error(
676             "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,...} ( locktime ) ( expiryheight )\n"
677             "\nCreate a transaction spending the given inputs and sending to the given addresses.\n"
678             "Returns hex-encoded raw transaction.\n"
679             "Note that the transaction's inputs are not signed, and\n"
680             "it is not stored in the wallet or transmitted to the network.\n"
681
682             "\nArguments:\n"
683             "1. \"transactions\"        (string, required) A json array of json objects\n"
684             "     [\n"
685             "       {\n"
686             "         \"txid\":\"id\",    (string, required) The transaction id\n"
687             "         \"vout\":n        (numeric, required) The output number\n"
688             "         \"sequence\":n    (numeric, optional) The sequence number\n"
689             "       }\n"
690             "       ,...\n"
691             "     ]\n"
692             "2. \"addresses\"           (string, required) a json object with addresses as keys and amounts as values\n"
693             "    {\n"
694             "      \"address\": x.xxx   (numeric, required) The key is the Komodo address, the value is the " + CURRENCY_UNIT + " amount\n"
695             "      ,...\n"
696             "    }\n"
697             "3. locktime              (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n"
698             "4. expiryheight          (numeric, optional, default=" + strprintf("%d", DEFAULT_TX_EXPIRY_DELTA) + ") Expiry height of transaction (if Overwinter is active)\n"
699             "\nResult:\n"
700             "\"transaction\"            (string) hex string of the transaction\n"
701
702             "\nExamples\n"
703             + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":0.01}\"")
704             + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\"")
705         );
706
707     LOCK(cs_main);
708     RPCTypeCheck(params, boost::assign::list_of(UniValue::VARR)(UniValue::VOBJ)(UniValue::VNUM)(UniValue::VNUM), true);
709     if (params[0].isNull() || params[1].isNull())
710         throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, arguments 1 and 2 must be non-null");
711
712     UniValue inputs = params[0].get_array();
713     UniValue sendTo = params[1].get_obj();
714
715     int nextBlockHeight = chainActive.Height() + 1;
716     CMutableTransaction rawTx = CreateNewContextualCMutableTransaction(
717         Params().GetConsensus(), nextBlockHeight);
718
719     if (params.size() > 2 && !params[2].isNull()) {
720         int64_t nLockTime = params[2].get_int64();
721         if (nLockTime < 0 || nLockTime > std::numeric_limits<uint32_t>::max())
722             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, locktime out of range");
723         rawTx.nLockTime = nLockTime;
724     }
725     
726     if (params.size() > 3 && !params[3].isNull()) {
727         if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
728             int64_t nExpiryHeight = params[3].get_int64();
729             if (nExpiryHeight < 0 || nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD) {
730                 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, expiryheight must be nonnegative and less than %d.", TX_EXPIRY_HEIGHT_THRESHOLD));
731             }
732             rawTx.nExpiryHeight = nExpiryHeight;
733         } else {
734             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expiryheight can only be used if Overwinter is active when the transaction is mined");
735         }
736     }
737
738     for (size_t idx = 0; idx < inputs.size(); idx++) {
739         const UniValue& input = inputs[idx];
740         const UniValue& o = input.get_obj();
741
742         uint256 txid = ParseHashO(o, "txid");
743
744         const UniValue& vout_v = find_value(o, "vout");
745         if (!vout_v.isNum())
746             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");
747         int nOutput = vout_v.get_int();
748         if (nOutput < 0)
749             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
750
751         uint32_t nSequence = (rawTx.nLockTime ? std::numeric_limits<uint32_t>::max() - 1 : std::numeric_limits<uint32_t>::max());
752
753         // set the sequence number if passed in the parameters object
754         const UniValue& sequenceObj = find_value(o, "sequence");
755         if (sequenceObj.isNum())
756             nSequence = sequenceObj.get_int();
757
758         CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence);
759
760         rawTx.vin.push_back(in);
761     }
762
763     std::set<CTxDestination> destinations;
764     vector<string> addrList = sendTo.getKeys();
765     for (const std::string& name_ : addrList) {
766         CTxDestination destination = DecodeDestination(name_);
767         if (!IsValidDestination(destination)) {
768             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Komodo address: ") + name_);
769         }
770
771         if (!destinations.insert(destination).second) {
772             throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + name_);
773         }
774
775         CScript scriptPubKey = GetScriptForDestination(destination);
776         CAmount nAmount = AmountFromValue(sendTo[name_]);
777
778         CTxOut out(nAmount, scriptPubKey);
779         rawTx.vout.push_back(out);
780     }
781
782     return EncodeHexTx(rawTx);
783 }
784
785 UniValue decoderawtransaction(const UniValue& params, bool fHelp)
786 {
787     if (fHelp || params.size() != 1)
788         throw runtime_error(
789             "decoderawtransaction \"hexstring\"\n"
790             "\nReturn a JSON object representing the serialized, hex-encoded transaction.\n"
791
792             "\nArguments:\n"
793             "1. \"hex\"      (string, required) The transaction hex string\n"
794
795             "\nResult:\n"
796             "{\n"
797             "  \"txid\" : \"id\",        (string) The transaction id\n"
798             "  \"overwintered\" : bool   (boolean) The Overwintered flag\n"
799             "  \"version\" : n,          (numeric) The version\n"
800             "  \"versiongroupid\": \"hex\"   (string, optional) The version group id (Overwintered txs)\n"
801             "  \"locktime\" : ttt,       (numeric) The lock time\n"
802             "  \"expiryheight\" : n,     (numeric, optional) Last valid block height for mining transaction (Overwintered txs)\n"
803             "  \"vin\" : [               (array of json objects)\n"
804             "     {\n"
805             "       \"txid\": \"id\",    (string) The transaction id\n"
806             "       \"vout\": n,         (numeric) The output number\n"
807             "       \"scriptSig\": {     (json object) The script\n"
808             "         \"asm\": \"asm\",  (string) asm\n"
809             "         \"hex\": \"hex\"   (string) hex\n"
810             "       },\n"
811             "       \"sequence\": n     (numeric) The script sequence number\n"
812             "     }\n"
813             "     ,...\n"
814             "  ],\n"
815             "  \"vout\" : [             (array of json objects)\n"
816             "     {\n"
817             "       \"value\" : x.xxx,            (numeric) The value in " + CURRENCY_UNIT + "\n"
818             "       \"n\" : n,                    (numeric) index\n"
819             "       \"scriptPubKey\" : {          (json object)\n"
820             "         \"asm\" : \"asm\",          (string) the asm\n"
821             "         \"hex\" : \"hex\",          (string) the hex\n"
822             "         \"reqSigs\" : n,            (numeric) The required sigs\n"
823             "         \"type\" : \"pubkeyhash\",  (string) The type, eg 'pubkeyhash'\n"
824             "         \"addresses\" : [           (json array of string)\n"
825             "           \"RTZMZHDFSTFQst8XmX2dR4DaH87cEUs3gC\"   (string) komodo address\n"
826             "           ,...\n"
827             "         ]\n"
828             "       }\n"
829             "     }\n"
830             "     ,...\n"
831             "  ],\n"
832             "  \"vjoinsplit\" : [        (array of json objects, only for version >= 2)\n"
833             "     {\n"
834             "       \"vpub_old\" : x.xxx,         (numeric) public input value in KMD\n"
835             "       \"vpub_new\" : x.xxx,         (numeric) public output value in KMD\n"
836             "       \"anchor\" : \"hex\",         (string) the anchor\n"
837             "       \"nullifiers\" : [            (json array of string)\n"
838             "         \"hex\"                     (string) input note nullifier\n"
839             "         ,...\n"
840             "       ],\n"
841             "       \"commitments\" : [           (json array of string)\n"
842             "         \"hex\"                     (string) output note commitment\n"
843             "         ,...\n"
844             "       ],\n"
845             "       \"onetimePubKey\" : \"hex\",  (string) the onetime public key used to encrypt the ciphertexts\n"
846             "       \"randomSeed\" : \"hex\",     (string) the random seed\n"
847             "       \"macs\" : [                  (json array of string)\n"
848             "         \"hex\"                     (string) input note MAC\n"
849             "         ,...\n"
850             "       ],\n"
851             "       \"proof\" : \"hex\",          (string) the zero-knowledge proof\n"
852             "       \"ciphertexts\" : [           (json array of string)\n"
853             "         \"hex\"                     (string) output note ciphertext\n"
854             "         ,...\n"
855             "       ]\n"
856             "     }\n"
857             "     ,...\n"
858             "  ],\n"
859             "}\n"
860
861             "\nExamples:\n"
862             + HelpExampleCli("decoderawtransaction", "\"hexstring\"")
863             + HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
864         );
865
866     LOCK(cs_main);
867     RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR));
868
869     CTransaction tx;
870
871     if (!DecodeHexTx(tx, params[0].get_str()))
872         throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
873
874     UniValue result(UniValue::VOBJ);
875     TxToJSON(tx, uint256(), result);
876
877     return result;
878 }
879
880 UniValue decodescript(const UniValue& params, bool fHelp)
881 {
882     if (fHelp || params.size() != 1)
883         throw runtime_error(
884             "decodescript \"hex\"\n"
885             "\nDecode a hex-encoded script.\n"
886             "\nArguments:\n"
887             "1. \"hex\"     (string) the hex encoded script\n"
888             "\nResult:\n"
889             "{\n"
890             "  \"asm\":\"asm\",   (string) Script public key\n"
891             "  \"hex\":\"hex\",   (string) hex encoded public key\n"
892             "  \"type\":\"type\", (string) The output type\n"
893             "  \"reqSigs\": n,    (numeric) The required signatures\n"
894             "  \"addresses\": [   (json array of string)\n"
895             "     \"address\"     (string) Komodo address\n"
896             "     ,...\n"
897             "  ],\n"
898             "  \"p2sh\",\"address\" (string) script address\n"
899             "}\n"
900             "\nExamples:\n"
901             + HelpExampleCli("decodescript", "\"hexstring\"")
902             + HelpExampleRpc("decodescript", "\"hexstring\"")
903         );
904
905     LOCK(cs_main);
906     RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR));
907
908     UniValue r(UniValue::VOBJ);
909     CScript script;
910     if (params[0].get_str().size() > 0){
911         vector<unsigned char> scriptData(ParseHexV(params[0], "argument"));
912         script = CScript(scriptData.begin(), scriptData.end());
913     } else {
914         // Empty scripts are valid
915     }
916     ScriptPubKeyToJSON(script, r, false);
917
918     r.push_back(Pair("p2sh", EncodeDestination(CScriptID(script))));
919     return r;
920 }
921
922 /** Pushes a JSON object for script verification or signing errors to vErrorsRet. */
923 static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std::string& strMessage)
924 {
925     UniValue entry(UniValue::VOBJ);
926     entry.push_back(Pair("txid", txin.prevout.hash.ToString()));
927     entry.push_back(Pair("vout", (uint64_t)txin.prevout.n));
928     entry.push_back(Pair("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
929     entry.push_back(Pair("sequence", (uint64_t)txin.nSequence));
930     entry.push_back(Pair("error", strMessage));
931     vErrorsRet.push_back(entry);
932 }
933
934 UniValue signrawtransaction(const UniValue& params, bool fHelp)
935 {
936     if (fHelp || params.size() < 1 || params.size() > 5)
937         throw runtime_error(
938             "signrawtransaction \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] [\"privatekey1\",...] sighashtype )\n"
939             "\nSign inputs for raw transaction (serialized, hex-encoded).\n"
940             "The second optional argument (may be null) is an array of previous transaction outputs that\n"
941             "this transaction depends on but may not yet be in the block chain.\n"
942             "The third optional argument (may be null) is an array of base58-encoded private\n"
943             "keys that, if given, will be the only keys used to sign the transaction.\n"
944 #ifdef ENABLE_WALLET
945             + HelpRequiringPassphrase() + "\n"
946 #endif
947
948             "\nArguments:\n"
949             "1. \"hexstring\"     (string, required) The transaction hex string\n"
950             "2. \"prevtxs\"       (string, optional) An json array of previous dependent transaction outputs\n"
951             "     [               (json array of json objects, or 'null' if none provided)\n"
952             "       {\n"
953             "         \"txid\":\"id\",             (string, required) The transaction id\n"
954             "         \"vout\":n,                  (numeric, required) The output number\n"
955             "         \"scriptPubKey\": \"hex\",   (string, required) script key\n"
956             "         \"redeemScript\": \"hex\",   (string, required for P2SH) redeem script\n"
957             "         \"amount\": value            (numeric, required) The amount spent\n"
958             "       }\n"
959             "       ,...\n"
960             "    ]\n"
961             "3. \"privatekeys\"     (string, optional) A json array of base58-encoded private keys for signing\n"
962             "    [                  (json array of strings, or 'null' if none provided)\n"
963             "      \"privatekey\"   (string) private key in base58-encoding\n"
964             "      ,...\n"
965             "    ]\n"
966             "4. \"sighashtype\"     (string, optional, default=ALL) The signature hash type. Must be one of\n"
967             "       \"ALL\"\n"
968             "       \"NONE\"\n"
969             "       \"SINGLE\"\n"
970             "       \"ALL|ANYONECANPAY\"\n"
971             "       \"NONE|ANYONECANPAY\"\n"
972             "       \"SINGLE|ANYONECANPAY\"\n"
973             "5.  \"branchid\"       (string, optional) The hex representation of the consensus branch id to sign with."
974             " This can be used to force signing with consensus rules that are ahead of the node's current height.\n"
975
976             "\nResult:\n"
977             "{\n"
978             "  \"hex\" : \"value\",           (string) The hex-encoded raw transaction with signature(s)\n"
979             "  \"complete\" : true|false,   (boolean) If the transaction has a complete set of signatures\n"
980             "  \"errors\" : [                 (json array of objects) Script verification errors (if there are any)\n"
981             "    {\n"
982             "      \"txid\" : \"hash\",           (string) The hash of the referenced, previous transaction\n"
983             "      \"vout\" : n,                (numeric) The index of the output to spent and used as input\n"
984             "      \"scriptSig\" : \"hex\",       (string) The hex-encoded signature script\n"
985             "      \"sequence\" : n,            (numeric) Script sequence number\n"
986             "      \"error\" : \"text\"           (string) Verification or signing error related to the input\n"
987             "    }\n"
988             "    ,...\n"
989             "  ]\n"
990             "}\n"
991
992             "\nExamples:\n"
993             + HelpExampleCli("signrawtransaction", "\"myhex\"")
994             + HelpExampleRpc("signrawtransaction", "\"myhex\"")
995         );
996
997 #ifdef ENABLE_WALLET
998     LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
999 #else
1000     LOCK(cs_main);
1001 #endif
1002     RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VARR)(UniValue::VARR)(UniValue::VSTR)(UniValue::VSTR), true);
1003
1004     vector<unsigned char> txData(ParseHexV(params[0], "argument 1"));
1005     CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
1006     vector<CMutableTransaction> txVariants;
1007     while (!ssData.empty()) {
1008         try {
1009             CMutableTransaction tx;
1010             ssData >> tx;
1011             txVariants.push_back(tx);
1012         }
1013         catch (const std::exception&) {
1014             throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
1015         }
1016     }
1017
1018     if (txVariants.empty())
1019         throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transaction");
1020
1021     // mergedTx will end up with all the signatures; it
1022     // starts as a clone of the rawtx:
1023     CMutableTransaction mergedTx(txVariants[0]);
1024
1025     // Fetch previous transactions (inputs):
1026     CCoinsView viewDummy;
1027     CCoinsViewCache view(&viewDummy);
1028     {
1029         LOCK(mempool.cs);
1030         CCoinsViewCache &viewChain = *pcoinsTip;
1031         CCoinsViewMemPool viewMempool(&viewChain, mempool);
1032         view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
1033
1034         BOOST_FOREACH(const CTxIn& txin, mergedTx.vin) {
1035             const uint256& prevHash = txin.prevout.hash;
1036             CCoins coins;
1037             view.AccessCoins(prevHash); // this is certainly allowed to fail
1038         }
1039
1040         view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
1041     }
1042
1043     bool fGivenKeys = false;
1044     CBasicKeyStore tempKeystore;
1045     if (params.size() > 2 && !params[2].isNull()) {
1046         fGivenKeys = true;
1047         UniValue keys = params[2].get_array();
1048         for (size_t idx = 0; idx < keys.size(); idx++) {
1049             UniValue k = keys[idx];
1050             CKey key = DecodeSecret(k.get_str());
1051             if (!key.IsValid())
1052                 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
1053             tempKeystore.AddKey(key);
1054         }
1055     }
1056 #ifdef ENABLE_WALLET
1057     else if (pwalletMain)
1058         EnsureWalletIsUnlocked();
1059 #endif
1060
1061     // Add previous txouts given in the RPC call:
1062     if (params.size() > 1 && !params[1].isNull()) {
1063         UniValue prevTxs = params[1].get_array();
1064         for (size_t idx = 0; idx < prevTxs.size(); idx++) {
1065             const UniValue& p = prevTxs[idx];
1066             if (!p.isObject())
1067                 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}");
1068
1069             UniValue prevOut = p.get_obj();
1070
1071             RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR));
1072
1073             uint256 txid = ParseHashO(prevOut, "txid");
1074
1075             int nOut = find_value(prevOut, "vout").get_int();
1076             if (nOut < 0)
1077                 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout must be positive");
1078
1079             vector<unsigned char> pkData(ParseHexO(prevOut, "scriptPubKey"));
1080             CScript scriptPubKey(pkData.begin(), pkData.end());
1081
1082             {
1083                 CCoinsModifier coins = view.ModifyCoins(txid);
1084                 if (coins->IsAvailable(nOut) && coins->vout[nOut].scriptPubKey != scriptPubKey) {
1085                     string err("Previous output scriptPubKey mismatch:\n");
1086                     err = err + ScriptToAsmStr(coins->vout[nOut].scriptPubKey) + "\nvs:\n"+
1087                         ScriptToAsmStr(scriptPubKey);
1088                     throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err);
1089                 }
1090                 if ((unsigned int)nOut >= coins->vout.size())
1091                     coins->vout.resize(nOut+1);
1092                 coins->vout[nOut].scriptPubKey = scriptPubKey;
1093                 coins->vout[nOut].nValue = 0;
1094                 if (prevOut.exists("amount")) {
1095                     coins->vout[nOut].nValue = AmountFromValue(find_value(prevOut, "amount"));
1096                 }
1097             }
1098
1099             // if redeemScript given and not using the local wallet (private keys
1100             // given), add redeemScript to the tempKeystore so it can be signed:
1101             if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) {
1102                 RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR)("redeemScript",UniValue::VSTR));
1103                 UniValue v = find_value(prevOut, "redeemScript");
1104                 if (!v.isNull()) {
1105                     vector<unsigned char> rsData(ParseHexV(v, "redeemScript"));
1106                     CScript redeemScript(rsData.begin(), rsData.end());
1107                     tempKeystore.AddCScript(redeemScript);
1108                 }
1109             }
1110         }
1111     }
1112
1113 #ifdef ENABLE_WALLET
1114     const CKeyStore& keystore = ((fGivenKeys || !pwalletMain) ? tempKeystore : *pwalletMain);
1115 #else
1116     const CKeyStore& keystore = tempKeystore;
1117 #endif
1118
1119     int nHashType = SIGHASH_ALL;
1120     if (params.size() > 3 && !params[3].isNull()) {
1121         static map<string, int> mapSigHashValues =
1122             boost::assign::map_list_of
1123             (string("ALL"), int(SIGHASH_ALL))
1124             (string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY))
1125             (string("NONE"), int(SIGHASH_NONE))
1126             (string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY))
1127             (string("SINGLE"), int(SIGHASH_SINGLE))
1128             (string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY))
1129             ;
1130         string strHashType = params[3].get_str();
1131         if (mapSigHashValues.count(strHashType))
1132             nHashType = mapSigHashValues[strHashType];
1133         else
1134             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param");
1135     }
1136
1137     bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
1138     // Use the approximate release height if it is greater so offline nodes 
1139     // have a better estimation of the current height and will be more likely to
1140     // determine the correct consensus branch ID.  Regtest mode ignores release height.
1141     int chainHeight = chainActive.Height() + 1;
1142
1143     // Grab the current consensus branch ID
1144     auto consensusBranchId = CurrentEpochBranchId(chainHeight, Params().GetConsensus());
1145
1146     if (params.size() > 4 && !params[4].isNull()) {
1147         consensusBranchId = ParseHexToUInt32(params[4].get_str());
1148         if (!IsConsensusBranchId(consensusBranchId)) {
1149             throw runtime_error(params[4].get_str() + " is not a valid consensus branch id");
1150         }
1151     } 
1152     
1153     // Script verification errors
1154     UniValue vErrors(UniValue::VARR);
1155
1156     // Use CTransaction for the constant parts of the
1157     // transaction to avoid rehashing.
1158     const CTransaction txConst(mergedTx);
1159     // Sign what we can:
1160     for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
1161         CTxIn& txin = mergedTx.vin[i];
1162         const CCoins* coins = view.AccessCoins(txin.prevout.hash);
1163         if (coins == NULL || !coins->IsAvailable(txin.prevout.n)) {
1164             TxInErrorToJSON(txin, vErrors, "Input not found or already spent");
1165             continue;
1166         }
1167         const CScript& prevPubKey = CCoinsViewCache::GetSpendFor(coins, txin);
1168         const CAmount& amount = coins->vout[txin.prevout.n].nValue;
1169
1170         SignatureData sigdata;
1171         // Only sign SIGHASH_SINGLE if there's a corresponding output:
1172         if (!fHashSingle || (i < mergedTx.vout.size()))
1173             ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mergedTx, i, amount, nHashType), prevPubKey, sigdata, consensusBranchId);
1174
1175         // ... and merge in other signatures:
1176         BOOST_FOREACH(const CMutableTransaction& txv, txVariants) {
1177             sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(txv, i), consensusBranchId);
1178         }
1179
1180         UpdateTransaction(mergedTx, i, sigdata);
1181
1182         ScriptError serror = SCRIPT_ERR_OK;
1183         if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount), consensusBranchId, &serror)) {
1184             TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror));
1185         }
1186     }
1187     bool fComplete = vErrors.empty();
1188
1189     UniValue result(UniValue::VOBJ);
1190     result.push_back(Pair("hex", EncodeHexTx(mergedTx)));
1191     result.push_back(Pair("complete", fComplete));
1192     if (!vErrors.empty()) {
1193         result.push_back(Pair("errors", vErrors));
1194     }
1195
1196     return result;
1197 }
1198
1199 UniValue sendrawtransaction(const UniValue& params, bool fHelp)
1200 {
1201     if (fHelp || params.size() < 1 || params.size() > 2)
1202         throw runtime_error(
1203             "sendrawtransaction \"hexstring\" ( allowhighfees )\n"
1204             "\nSubmits raw transaction (serialized, hex-encoded) to local node and network.\n"
1205             "\nAlso see createrawtransaction and signrawtransaction calls.\n"
1206             "\nArguments:\n"
1207             "1. \"hexstring\"    (string, required) The hex string of the raw transaction)\n"
1208             "2. allowhighfees    (boolean, optional, default=false) Allow high fees\n"
1209             "\nResult:\n"
1210             "\"hex\"             (string) The transaction hash in hex\n"
1211             "\nExamples:\n"
1212             "\nCreate a transaction\n"
1213             + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") +
1214             "Sign the transaction, and get back the hex\n"
1215             + HelpExampleCli("signrawtransaction", "\"myhex\"") +
1216             "\nSend the transaction (signed hex)\n"
1217             + HelpExampleCli("sendrawtransaction", "\"signedhex\"") +
1218             "\nAs a json rpc call\n"
1219             + HelpExampleRpc("sendrawtransaction", "\"signedhex\"")
1220         );
1221
1222     LOCK(cs_main);
1223     RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VBOOL));
1224
1225     // parse hex string from parameter
1226     CTransaction tx;
1227     if (!DecodeHexTx(tx, params[0].get_str()))
1228         throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
1229     uint256 hashTx = tx.GetHash();
1230
1231     bool fOverrideFees = false;
1232     if (params.size() > 1)
1233         fOverrideFees = params[1].get_bool();
1234
1235     CCoinsViewCache &view = *pcoinsTip;
1236     const CCoins* existingCoins = view.AccessCoins(hashTx);
1237     bool fHaveMempool = mempool.exists(hashTx);
1238     bool fHaveChain = existingCoins && existingCoins->nHeight < 1000000000;
1239     if (!fHaveMempool && !fHaveChain) {
1240         // push to local node and sync with wallets
1241         CValidationState state;
1242         bool fMissingInputs;
1243         if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees)) {
1244             if (state.IsInvalid()) {
1245                 throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
1246             } else {
1247                 if (fMissingInputs) {
1248                     throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs");
1249                 }
1250                 throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason());
1251             }
1252         }
1253     } else if (fHaveChain) {
1254         throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain");
1255     }    
1256     RelayTransaction(tx);
1257
1258     return hashTx.GetHex();
1259 }
1260
1261 static const CRPCCommand commands[] =
1262 { //  category              name                      actor (function)         okSafeMode
1263   //  --------------------- ------------------------  -----------------------  ----------
1264     { "rawtransactions",    "getrawtransaction",      &getrawtransaction,      true  },
1265     { "rawtransactions",    "createrawtransaction",   &createrawtransaction,   true  },
1266     { "rawtransactions",    "decoderawtransaction",   &decoderawtransaction,   true  },
1267     { "rawtransactions",    "decodescript",           &decodescript,           true  },
1268     { "rawtransactions",    "sendrawtransaction",     &sendrawtransaction,     false },
1269     { "rawtransactions",    "signrawtransaction",     &signrawtransaction,     false }, /* uses wallet if enabled */
1270
1271     { "blockchain",         "gettxoutproof",          &gettxoutproof,          true  },
1272     { "blockchain",         "verifytxoutproof",       &verifytxoutproof,       true  },
1273 };
1274
1275 void RegisterRawTransactionRPCCommands(CRPCTable &tableRPC)
1276 {
1277     for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
1278         tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
1279 }
This page took 0.10426 seconds and 4 git commands to generate.