1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2015 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 #include "consensus/upgrades.h"
7 #include "consensus/validation.h"
10 #include "deprecation.h"
14 #include "merkleblock.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"
24 #include "wallet/wallet.h"
27 #include "komodo_defs.h"
31 #include <boost/assign/list_of.hpp>
37 extern char ASSETCHAINS_SYMBOL[];
39 void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex)
42 vector<CTxDestination> addresses;
45 out.push_back(Pair("asm", ScriptToAsmStr(scriptPubKey)));
47 out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
49 if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired))
51 out.push_back(Pair("type", GetTxnOutputType(type)));
55 out.push_back(Pair("reqSigs", nRequired));
56 out.push_back(Pair("type", GetTxnOutputType(type)));
58 UniValue a(UniValue::VARR);
59 for (const CTxDestination& addr : addresses) {
60 a.push_back(EncodeDestination(addr));
62 out.push_back(Pair("addresses", a));
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);
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));
77 joinsplit.push_back(Pair("anchor", jsdescription.anchor.GetHex()));
80 UniValue nullifiers(UniValue::VARR);
81 BOOST_FOREACH(const uint256 nf, jsdescription.nullifiers) {
82 nullifiers.push_back(nf.GetHex());
84 joinsplit.push_back(Pair("nullifiers", nullifiers));
88 UniValue commitments(UniValue::VARR);
89 BOOST_FOREACH(const uint256 commitment, jsdescription.commitments) {
90 commitments.push_back(commitment.GetHex());
92 joinsplit.push_back(Pair("commitments", commitments));
95 joinsplit.push_back(Pair("onetimePubKey", jsdescription.ephemeralKey.GetHex()));
96 joinsplit.push_back(Pair("randomSeed", jsdescription.randomSeed.GetHex()));
99 UniValue macs(UniValue::VARR);
100 BOOST_FOREACH(const uint256 mac, jsdescription.macs) {
101 macs.push_back(mac.GetHex());
103 joinsplit.push_back(Pair("macs", macs));
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())));
112 UniValue ciphertexts(UniValue::VARR);
113 for (const ZCNoteEncryption::Ciphertext ct : jsdescription.ciphertexts) {
114 ciphertexts.push_back(HexStr(ct.begin(), ct.end()));
116 joinsplit.push_back(Pair("ciphertexts", ciphertexts));
119 vjoinsplit.push_back(joinsplit);
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);
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);
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);
156 int32_t myIsutxo_spent(uint256 &spenttxid,uint256 txid,int32_t vout)
158 CSpentIndexValue spentInfo; CSpentIndexKey spentKey(txid,vout);
159 if ( GetSpentIndex(spentKey,spentInfo) )
161 spenttxid = spentInfo.txid;
162 return((int32_t)spentInfo.inputIndex);
163 // out.push_back(Pair("spentHeight", spentInfo.blockHeight));
165 memset(&spenttxid,0,sizeof(spenttxid));
169 void TxToJSONExpanded(const CTransaction& tx, const uint256 hashBlock, UniValue& entry, int nHeight = 0, int nConfirmations = 0, int nBlockTime = 0)
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)));
178 entry.push_back(Pair("locktime", (int64_t)tx.nLockTime));
179 if (tx.fOverwintered) {
180 entry.push_back(Pair("expiryheight", (int64_t)tx.nExpiryHeight));
182 UniValue vin(UniValue::VARR);
183 BOOST_FOREACH(const CTxIn& txin, tx.vin) {
184 UniValue in(UniValue::VOBJ);
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"));
191 in.push_back(Pair("txid", txin.prevout.hash.GetHex()));
192 in.push_back(Pair("vout", (int64_t)txin.prevout.n));
194 uint256 hash; CTransaction tx; CTxDestination address;
195 if (GetTransaction(txin.prevout.hash,tx,hash,false))
197 if (ExtractDestination(tx.vout[txin.prevout.n].scriptPubKey, address))
198 in.push_back(Pair("address", CBitcoinAddress(address).ToString()));
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));
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()));
215 else if (spentInfo.addressType == 2) {
216 in.push_back(Pair("address", CBitcoinAddress(CScriptID(spentInfo.addressHash)).ToString()));
220 in.push_back(Pair("sequence", (int64_t)txin.nSequence));
223 entry.push_back(Pair("vin", vin));
224 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
225 CBlockIndex *tipindex,*pindex = it->second;
227 UniValue vout(UniValue::VARR);
228 for (unsigned int i = 0; i < tx.vout.size(); i++)
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 )
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)));
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));
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));
256 entry.push_back(Pair("vout", vout));
258 UniValue vjoinsplit = TxJoinSplitToJSON(tx);
259 entry.push_back(Pair("vjoinsplit", vjoinsplit));
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())));
272 if (!hashBlock.IsNull()) {
273 entry.push_back(Pair("blockhash", hashBlock.GetHex()));
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));
281 entry.push_back(Pair("height", -1));
282 entry.push_back(Pair("confirmations", 0));
288 void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
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)));
296 entry.push_back(Pair("locktime", (int64_t)tx.nLockTime));
297 if (tx.fOverwintered) {
298 entry.push_back(Pair("expiryheight", (int64_t)tx.nExpiryHeight));
300 UniValue vin(UniValue::VARR);
301 BOOST_FOREACH(const CTxIn& txin, tx.vin) {
302 UniValue in(UniValue::VOBJ);
304 in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
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));
313 in.push_back(Pair("sequence", (int64_t)txin.nSequence));
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;
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 )
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)));
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));
338 entry.push_back(Pair("vout", vout));
340 UniValue vjoinsplit = TxJoinSplitToJSON(tx);
341 entry.push_back(Pair("vjoinsplit", vjoinsplit));
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())));
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()));
365 entry.push_back(Pair("confirmations", 0));
370 UniValue getrawtransaction(const UniValue& params, bool fHelp)
372 if (fHelp || params.size() < 1 || params.size() > 2)
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"
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"
386 "\nResult (if verbose is not set or set to 0):\n"
387 "\"data\" (string) The serialized, hex-encoded data for 'txid'\n"
389 "\nResult (if verbose > 0):\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"
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"
404 " \"sequence\": n (numeric) The script sequence number\n"
408 " \"vout\" : [ (array of json objects)\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"
425 " \"vjoinsplit\" : [ (array of json objects, only for version >= 2)\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"
434 " \"commitments\" : [ (json array of string)\n"
435 " \"hex\" (string) output note commitment\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"
444 " \"proof\" : \"hex\", (string) the zero-knowledge proof\n"
445 " \"ciphertexts\" : [ (json array of string)\n"
446 " \"hex\" (string) output note ciphertext\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"
459 + HelpExampleCli("getrawtransaction", "\"mytxid\"")
460 + HelpExampleCli("getrawtransaction", "\"mytxid\" 1")
461 + HelpExampleRpc("getrawtransaction", "\"mytxid\", 1")
465 uint256 hash = ParseHashV(params[0], "parameter 1");
467 bool fVerbose = false;
468 if (params.size() > 1)
469 fVerbose = (params[1].get_int() != 0);
474 int nConfirmations = 0;
479 if (!GetTransaction(hash, tx, hashBlock, true))
480 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction");
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();
492 nBlockTime = pindex->GetBlockTime();
497 string strHex = EncodeHexTx(tx);
502 UniValue result(UniValue::VOBJ);
503 result.push_back(Pair("hex", strHex));
504 TxToJSONExpanded(tx, hashBlock, result, nHeight, nConfirmations, nBlockTime);
508 int32_t gettxout_scriptPubKey(uint8_t *scriptPubKey,int32_t maxsize,uint256 txid,int32_t n)
510 int32_t i,m; uint8_t *ptr;
513 for (iter=0; iter<2; iter++)
518 CCoinsViewMemPool view(pcoinsTip,mempool);
519 if ( view.GetCoins(txid,coins) == 0 )
521 //fprintf(stderr,"cant get view\n");
524 mempool.pruneSpent(txid, coins); // TODO: this should be done by the CCoinsViewMemPool
526 else if ( pcoinsTip->GetCoins(txid,coins) == 0 )
528 //fprintf(stderr,"cant get pcoinsTip->GetCoins\n");
531 if ( n < 0 || (unsigned int)n >= coins.vout.size() || coins.vout[n].IsNull() )
533 fprintf(stderr,"iter.%d n.%d vs voutsize.%d\n",iter,n,(int32_t)coins.vout.size());
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];
544 if ( GetTransaction(txid,tx,hashBlock,false) == 0 )
546 else if ( n <= tx.vout.size() ) // vout.size() seems off by 1
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");
558 UniValue gettxoutproof(const UniValue& params, bool fHelp)
560 if (fHelp || (params.size() != 1 && params.size() != 2))
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"
570 "1. \"txids\" (string) A json array of txids to filter\n"
572 " \"txid\" (string) A transaction hash\n"
575 "2. \"block hash\" (string, optional) If specified, looks for txid in the block with this hash\n"
577 "\"data\" (string) A string that is a serialized, hex-encoded data for the proof.\n"
580 set<uint256> setTxids;
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);
596 CBlockIndex* pblockindex = NULL;
599 if (params.size() > 1)
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];
607 if (pcoinsTip->GetCoins(oneTxid, coins) && coins.nHeight > 0 && coins.nHeight <= chainActive.Height())
608 pblockindex = chainActive[coins.nHeight];
611 if (pblockindex == NULL)
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];
622 if(!ReadBlockFromDisk(block, pblockindex,1))
623 throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
625 unsigned int ntxFound = 0;
626 BOOST_FOREACH(const CTransaction&tx, block.vtx)
627 if (setTxids.count(tx.GetHash()))
629 if (ntxFound != setTxids.size())
630 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "(Not all) transactions not found in specified block");
632 CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION);
633 CMerkleBlock mb(block, setTxids);
635 std::string strHex = HexStr(ssMB.begin(), ssMB.end());
639 UniValue verifytxoutproof(const UniValue& params, bool fHelp)
641 if (fHelp || params.size() != 1)
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"
647 "1. \"proof\" (string, required) The hex-encoded proof generated by gettxoutproof\n"
649 "[\"txid\"] (array, strings) The txid(s) which the proof commits to, or empty array if the proof is invalid\n"
652 CDataStream ssMB(ParseHexV(params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION);
653 CMerkleBlock merkleBlock;
656 UniValue res(UniValue::VARR);
658 vector<uint256> vMatch;
659 if (merkleBlock.txn.ExtractMatches(vMatch) != merkleBlock.header.hashMerkleRoot)
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");
667 BOOST_FOREACH(const uint256& hash, vMatch)
668 res.push_back(hash.GetHex());
672 UniValue createrawtransaction(const UniValue& params, bool fHelp)
674 if (fHelp || params.size() < 2 || params.size() > 4)
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"
683 "1. \"transactions\" (string, required) A json array of json objects\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"
692 "2. \"addresses\" (string, required) a json object with addresses as keys and amounts as values\n"
694 " \"address\": x.xxx (numeric, required) The key is the Komodo address, the value is the " + CURRENCY_UNIT + " amount\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"
700 "\"transaction\" (string) hex string of the transaction\n"
703 + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":0.01}\"")
704 + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\"")
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");
712 UniValue inputs = params[0].get_array();
713 UniValue sendTo = params[1].get_obj();
715 int nextBlockHeight = chainActive.Height() + 1;
716 CMutableTransaction rawTx = CreateNewContextualCMutableTransaction(
717 Params().GetConsensus(), nextBlockHeight);
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;
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));
732 rawTx.nExpiryHeight = nExpiryHeight;
734 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expiryheight can only be used if Overwinter is active when the transaction is mined");
738 for (size_t idx = 0; idx < inputs.size(); idx++) {
739 const UniValue& input = inputs[idx];
740 const UniValue& o = input.get_obj();
742 uint256 txid = ParseHashO(o, "txid");
744 const UniValue& vout_v = find_value(o, "vout");
746 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");
747 int nOutput = vout_v.get_int();
749 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
751 uint32_t nSequence = (rawTx.nLockTime ? std::numeric_limits<uint32_t>::max() - 1 : std::numeric_limits<uint32_t>::max());
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();
758 CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence);
760 rawTx.vin.push_back(in);
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_);
771 if (!destinations.insert(destination).second) {
772 throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + name_);
775 CScript scriptPubKey = GetScriptForDestination(destination);
776 CAmount nAmount = AmountFromValue(sendTo[name_]);
778 CTxOut out(nAmount, scriptPubKey);
779 rawTx.vout.push_back(out);
782 return EncodeHexTx(rawTx);
785 UniValue decoderawtransaction(const UniValue& params, bool fHelp)
787 if (fHelp || params.size() != 1)
789 "decoderawtransaction \"hexstring\"\n"
790 "\nReturn a JSON object representing the serialized, hex-encoded transaction.\n"
793 "1. \"hex\" (string, required) The transaction hex string\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"
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"
811 " \"sequence\": n (numeric) The script sequence number\n"
815 " \"vout\" : [ (array of json objects)\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"
832 " \"vjoinsplit\" : [ (array of json objects, only for version >= 2)\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"
841 " \"commitments\" : [ (json array of string)\n"
842 " \"hex\" (string) output note commitment\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"
851 " \"proof\" : \"hex\", (string) the zero-knowledge proof\n"
852 " \"ciphertexts\" : [ (json array of string)\n"
853 " \"hex\" (string) output note ciphertext\n"
862 + HelpExampleCli("decoderawtransaction", "\"hexstring\"")
863 + HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
867 RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR));
871 if (!DecodeHexTx(tx, params[0].get_str()))
872 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
874 UniValue result(UniValue::VOBJ);
875 TxToJSON(tx, uint256(), result);
880 UniValue decodescript(const UniValue& params, bool fHelp)
882 if (fHelp || params.size() != 1)
884 "decodescript \"hex\"\n"
885 "\nDecode a hex-encoded script.\n"
887 "1. \"hex\" (string) the hex encoded script\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"
898 " \"p2sh\",\"address\" (string) script address\n"
901 + HelpExampleCli("decodescript", "\"hexstring\"")
902 + HelpExampleRpc("decodescript", "\"hexstring\"")
906 RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR));
908 UniValue r(UniValue::VOBJ);
910 if (params[0].get_str().size() > 0){
911 vector<unsigned char> scriptData(ParseHexV(params[0], "argument"));
912 script = CScript(scriptData.begin(), scriptData.end());
914 // Empty scripts are valid
916 ScriptPubKeyToJSON(script, r, false);
918 r.push_back(Pair("p2sh", EncodeDestination(CScriptID(script))));
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)
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);
934 UniValue signrawtransaction(const UniValue& params, bool fHelp)
936 if (fHelp || params.size() < 1 || params.size() > 5)
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"
945 + HelpRequiringPassphrase() + "\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"
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"
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"
966 "4. \"sighashtype\" (string, optional, default=ALL) The signature hash type. Must be one of\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"
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"
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"
993 + HelpExampleCli("signrawtransaction", "\"myhex\"")
994 + HelpExampleRpc("signrawtransaction", "\"myhex\"")
998 LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
1002 RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VARR)(UniValue::VARR)(UniValue::VSTR)(UniValue::VSTR), true);
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()) {
1009 CMutableTransaction tx;
1011 txVariants.push_back(tx);
1013 catch (const std::exception&) {
1014 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
1018 if (txVariants.empty())
1019 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transaction");
1021 // mergedTx will end up with all the signatures; it
1022 // starts as a clone of the rawtx:
1023 CMutableTransaction mergedTx(txVariants[0]);
1025 // Fetch previous transactions (inputs):
1026 CCoinsView viewDummy;
1027 CCoinsViewCache view(&viewDummy);
1030 CCoinsViewCache &viewChain = *pcoinsTip;
1031 CCoinsViewMemPool viewMempool(&viewChain, mempool);
1032 view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
1034 BOOST_FOREACH(const CTxIn& txin, mergedTx.vin) {
1035 const uint256& prevHash = txin.prevout.hash;
1037 view.AccessCoins(prevHash); // this is certainly allowed to fail
1040 view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
1043 bool fGivenKeys = false;
1044 CBasicKeyStore tempKeystore;
1045 if (params.size() > 2 && !params[2].isNull()) {
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());
1052 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
1053 tempKeystore.AddKey(key);
1056 #ifdef ENABLE_WALLET
1057 else if (pwalletMain)
1058 EnsureWalletIsUnlocked();
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];
1067 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}");
1069 UniValue prevOut = p.get_obj();
1071 RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR));
1073 uint256 txid = ParseHashO(prevOut, "txid");
1075 int nOut = find_value(prevOut, "vout").get_int();
1077 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout must be positive");
1079 vector<unsigned char> pkData(ParseHexO(prevOut, "scriptPubKey"));
1080 CScript scriptPubKey(pkData.begin(), pkData.end());
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);
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"));
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");
1105 vector<unsigned char> rsData(ParseHexV(v, "redeemScript"));
1106 CScript redeemScript(rsData.begin(), rsData.end());
1107 tempKeystore.AddCScript(redeemScript);
1113 #ifdef ENABLE_WALLET
1114 const CKeyStore& keystore = ((fGivenKeys || !pwalletMain) ? tempKeystore : *pwalletMain);
1116 const CKeyStore& keystore = tempKeystore;
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))
1130 string strHashType = params[3].get_str();
1131 if (mapSigHashValues.count(strHashType))
1132 nHashType = mapSigHashValues[strHashType];
1134 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param");
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;
1143 // Grab the current consensus branch ID
1144 auto consensusBranchId = CurrentEpochBranchId(chainHeight, Params().GetConsensus());
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");
1153 // Script verification errors
1154 UniValue vErrors(UniValue::VARR);
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");
1167 const CScript& prevPubKey = CCoinsViewCache::GetSpendFor(coins, txin);
1168 const CAmount& amount = coins->vout[txin.prevout.n].nValue;
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);
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);
1180 UpdateTransaction(mergedTx, i, sigdata);
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));
1187 bool fComplete = vErrors.empty();
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));
1199 UniValue sendrawtransaction(const UniValue& params, bool fHelp)
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"
1207 "1. \"hexstring\" (string, required) The hex string of the raw transaction)\n"
1208 "2. allowhighfees (boolean, optional, default=false) Allow high fees\n"
1210 "\"hex\" (string) The transaction hash in hex\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\"")
1223 RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VBOOL));
1225 // parse hex string from parameter
1227 if (!DecodeHexTx(tx, params[0].get_str()))
1228 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
1229 uint256 hashTx = tx.GetHash();
1231 bool fOverrideFees = false;
1232 if (params.size() > 1)
1233 fOverrideFees = params[1].get_bool();
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()));
1247 if (fMissingInputs) {
1248 throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs");
1250 throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason());
1253 } else if (fHaveChain) {
1254 throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain");
1256 RelayTransaction(tx);
1258 return hashTx.GetHex();
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 */
1271 { "blockchain", "gettxoutproof", &gettxoutproof, true },
1272 { "blockchain", "verifytxoutproof", &verifytxoutproof, true },
1275 void RegisterRawTransactionRPCCommands(CRPCTable &tableRPC)
1277 for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
1278 tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);