Raven Core  3.0.0
P2P Digital Currency
rawtransaction.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 The Bitcoin Core developers
3 // Copyright (c) 2017-2019 The Raven Core developers
4 // Distributed under the MIT software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 #include "base58.h"
8 #include "chain.h"
9 #include "coins.h"
10 #include "consensus/validation.h"
11 #include "core_io.h"
12 #include "init.h"
13 #include "keystore.h"
14 #include "validation.h"
15 #include "merkleblock.h"
16 #include "net.h"
17 #include "policy/policy.h"
18 #include "policy/rbf.h"
19 #include "primitives/transaction.h"
20 #include "rpc/safemode.h"
21 #include "rpc/server.h"
22 #include "script/script.h"
23 #include "script/script_error.h"
24 #include "script/sign.h"
25 #include "script/standard.h"
26 #include "txmempool.h"
27 #include "uint256.h"
28 #include "utilstrencodings.h"
29 #ifdef ENABLE_WALLET
30 #include "wallet/rpcwallet.h"
31 #include "wallet/wallet.h"
32 #endif
33 
34 #include <stdint.h>
35 #include "assets/assets.h"
36 
37 #include <univalue.h>
38 #include <tinyformat.h>
39 
40 void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry, bool expanded = false)
41 {
42  // Call into TxToUniv() in raven-common to decode the transaction hex.
43  //
44  // Blockchain contextual information (confirmations and blocktime) is not
45  // available to code in raven-common, so we query them here and push the
46  // data into the returned UniValue.
47  TxToUniv(tx, uint256(), entry, true, RPCSerializationFlags());
48 
49  if (expanded) {
50  uint256 txid = tx.GetHash();
51  if (!(tx.IsCoinBase())) {
52  const UniValue& oldVin = entry["vin"];
53  UniValue newVin(UniValue::VARR);
54  for (unsigned int i = 0; i < tx.vin.size(); i++) {
55  const CTxIn& txin = tx.vin[i];
56  UniValue in = oldVin[i];
57 
58  // Add address and value info if spentindex enabled
59  CSpentIndexValue spentInfo;
60  CSpentIndexKey spentKey(txin.prevout.hash, txin.prevout.n);
61  if (GetSpentIndex(spentKey, spentInfo)) {
62  in.pushKV("value", ValueFromAmount(spentInfo.satoshis));
63  in.pushKV("valueSat", spentInfo.satoshis);
64  if (spentInfo.addressType == 1) {
65  in.pushKV("address", CRavenAddress(CKeyID(spentInfo.addressHash)).ToString());
66  } else if (spentInfo.addressType == 2) {
67  in.pushKV("address", CRavenAddress(CScriptID(spentInfo.addressHash)).ToString());
68  }
69  }
70  newVin.push_back(in);
71  }
72  entry.pushKV("vin", newVin);
73  }
74 
75  const UniValue& oldVout = entry["vout"];
76  UniValue newVout(UniValue::VARR);
77  for (unsigned int i = 0; i < tx.vout.size(); i++) {
78  const CTxOut& txout = tx.vout[i];
79  UniValue out = oldVout[i];
80 
81  // Add spent information if spentindex is enabled
82  CSpentIndexValue spentInfo;
83  CSpentIndexKey spentKey(txid, i);
84  if (GetSpentIndex(spentKey, spentInfo)) {
85  out.pushKV("spentTxId", spentInfo.txid.GetHex());
86  out.pushKV("spentIndex", (int)spentInfo.inputIndex);
87  out.pushKV("spentHeight", spentInfo.blockHeight);
88  }
89 
90  out.pushKV("valueSat", txout.nValue);
91  newVout.push_back(out);
92  }
93  entry.pushKV("vout", newVout);
94  }
95 
96  if (!hashBlock.IsNull()) {
97  entry.pushKV("blockhash", hashBlock.GetHex());
98  BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
99  if (mi != mapBlockIndex.end() && (*mi).second) {
100  CBlockIndex* pindex = (*mi).second;
101  if (chainActive.Contains(pindex)) {
102  entry.pushKV("height", pindex->nHeight);
103  entry.pushKV("confirmations", 1 + chainActive.Height() - pindex->nHeight);
104  entry.pushKV("time", pindex->GetBlockTime());
105  entry.pushKV("blocktime", pindex->GetBlockTime());
106  } else {
107  entry.pushKV("height", -1);
108  entry.pushKV("confirmations", 0);
109  }
110  }
111  }
112 }
113 
115 {
116  if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
117  throw std::runtime_error(
118  "getrawtransaction \"txid\" ( verbose )\n"
119 
120  "\nNOTE: By default this function only works for mempool transactions. If the -txindex option is\n"
121  "enabled, it also works for blockchain transactions.\n"
122  "DEPRECATED: for now, it also works for transactions with unspent outputs.\n"
123 
124  "\nReturn the raw transaction data.\n"
125  "\nIf verbose is 'true', returns an Object with information about 'txid'.\n"
126  "If verbose is 'false' or omitted, returns a string that is serialized, hex-encoded data for 'txid'.\n"
127 
128  "\nArguments:\n"
129  "1. \"txid\" (string, required) The transaction id\n"
130  "2. verbose (bool, optional, default=false) If false, return a string, otherwise return a json object\n"
131 
132  "\nResult (if verbose is not set or set to false):\n"
133  "\"data\" (string) The serialized, hex-encoded data for 'txid'\n"
134 
135  "\nResult (if verbose is set to true):\n"
136  "{\n"
137  " \"hex\" : \"data\", (string) The serialized, hex-encoded data for 'txid'\n"
138  " \"txid\" : \"id\", (string) The transaction id (same as provided)\n"
139  " \"hash\" : \"id\", (string) The transaction hash (differs from txid for witness transactions)\n"
140  " \"size\" : n, (numeric) The serialized transaction size\n"
141  " \"vsize\" : n, (numeric) The virtual transaction size (differs from size for witness transactions)\n"
142  " \"version\" : n, (numeric) The version\n"
143  " \"locktime\" : ttt, (numeric) The lock time\n"
144  " \"vin\" : [ (array of json objects)\n"
145  " {\n"
146  " \"txid\": \"id\", (string) The transaction id\n"
147  " \"vout\": n, (numeric) \n"
148  " \"scriptSig\": { (json object) The script\n"
149  " \"asm\": \"asm\", (string) asm\n"
150  " \"hex\": \"hex\" (string) hex\n"
151  " },\n"
152  " \"sequence\": n (numeric) The script sequence number\n"
153  " \"txinwitness\": [\"hex\", ...] (array of string) hex-encoded witness data (if any)\n"
154  " }\n"
155  " ,...\n"
156  " ],\n"
157  " \"vout\" : [ (array of json objects)\n"
158  " {\n"
159  " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n"
160  " \"n\" : n, (numeric) index\n"
161  " \"scriptPubKey\" : { (json object)\n"
162  " \"asm\" : \"asm\", (string) the asm\n"
163  " \"hex\" : \"hex\", (string) the hex\n"
164  " \"reqSigs\" : n, (numeric) The required sigs\n"
165  " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
166  " \"addresses\" : [ (json array of string)\n"
167  " \"address\" (string) raven address\n"
168  " ,...\n"
169  " ]\n"
170  " }\n"
171  " }\n"
172  " ,...\n"
173  " ],\n"
174  " \"blockhash\" : \"hash\", (string) the block hash\n"
175  " \"confirmations\" : n, (numeric) The confirmations\n"
176  " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT)\n"
177  " \"blocktime\" : ttt (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
178  "}\n"
179 
180  "\nExamples:\n"
181  + HelpExampleCli("getrawtransaction", "\"mytxid\"")
182  + HelpExampleCli("getrawtransaction", "\"mytxid\" true")
183  + HelpExampleRpc("getrawtransaction", "\"mytxid\", true")
184  );
185 
186  LOCK(cs_main);
187 
188  uint256 hash = ParseHashV(request.params[0], "parameter 1");
189 
190  // Accept either a bool (true) or a num (>=1) to indicate verbose output.
191  bool fVerbose = false;
192  if (!request.params[1].isNull()) {
193  if (request.params[1].isNum()) {
194  if (request.params[1].get_int() != 0) {
195  fVerbose = true;
196  }
197  }
198  else if(request.params[1].isBool()) {
199  if(request.params[1].isTrue()) {
200  fVerbose = true;
201  }
202  }
203  else {
204  throw JSONRPCError(RPC_TYPE_ERROR, "Invalid type provided. Verbose parameter must be a boolean.");
205  }
206  }
207 
208  CTransactionRef tx;
209 
210  uint256 hashBlock;
211  if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true))
212  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string(fTxIndex ? "No such mempool or blockchain transaction"
213  : "No such mempool transaction. Use -txindex to enable blockchain transaction queries") +
214  ". Use gettransaction for wallet transactions.");
215 
216  if (!fVerbose)
217  return EncodeHexTx(*tx, RPCSerializationFlags());
218 
219  UniValue result(UniValue::VOBJ);
220  TxToJSON(*tx, hashBlock, result, true);
221 
222  return result;
223 }
224 
226 {
227  if (request.fHelp || (request.params.size() != 1 && request.params.size() != 2))
228  throw std::runtime_error(
229  "gettxoutproof [\"txid\",...] ( blockhash )\n"
230  "\nReturns a hex-encoded proof that \"txid\" was included in a block.\n"
231  "\nNOTE: By default this function only works sometimes. This is when there is an\n"
232  "unspent output in the utxo for this transaction. To make it always work,\n"
233  "you need to maintain a transaction index, using the -txindex command line option or\n"
234  "specify the block in which the transaction is included manually (by blockhash).\n"
235  "\nArguments:\n"
236  "1. \"txids\" (string) A json array of txids to filter\n"
237  " [\n"
238  " \"txid\" (string) A transaction hash\n"
239  " ,...\n"
240  " ]\n"
241  "2. \"blockhash\" (string, optional) If specified, looks for txid in the block with this hash\n"
242  "\nResult:\n"
243  "\"data\" (string) A string that is a serialized, hex-encoded data for the proof.\n"
244  );
245 
246  std::set<uint256> setTxids;
247  uint256 oneTxid;
248  UniValue txids = request.params[0].get_array();
249  for (unsigned int idx = 0; idx < txids.size(); idx++) {
250  const UniValue& txid = txids[idx];
251  if (txid.get_str().length() != 64 || !IsHex(txid.get_str()))
252  throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid txid ")+txid.get_str());
253  uint256 hash(uint256S(txid.get_str()));
254  if (setTxids.count(hash))
255  throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated txid: ")+txid.get_str());
256  setTxids.insert(hash);
257  oneTxid = hash;
258  }
259 
260  LOCK(cs_main);
261 
262  CBlockIndex* pblockindex = nullptr;
263 
264  uint256 hashBlock;
265  if (!request.params[1].isNull())
266  {
267  hashBlock = uint256S(request.params[1].get_str());
268  if (!mapBlockIndex.count(hashBlock))
269  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
270  pblockindex = mapBlockIndex[hashBlock];
271  } else {
272  // Loop through txids and try to find which block they're in. Exit loop once a block is found.
273  for (const auto& tx : setTxids) {
274  const Coin& coin = AccessByTxid(*pcoinsTip, tx);
275  if (!coin.IsSpent()) {
276  pblockindex = chainActive[coin.nHeight];
277  break;
278  }
279  }
280  }
281 
282  if (pblockindex == nullptr)
283  {
284  CTransactionRef tx;
285  if (!GetTransaction(oneTxid, tx, Params().GetConsensus(), hashBlock, false) || hashBlock.IsNull())
286  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block");
287  if (!mapBlockIndex.count(hashBlock))
288  throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt");
289  pblockindex = mapBlockIndex[hashBlock];
290  }
291 
292  CBlock block;
293  if(!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
294  throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
295 
296  unsigned int ntxFound = 0;
297  for (const auto& tx : block.vtx)
298  if (setTxids.count(tx->GetHash()))
299  ntxFound++;
300  if (ntxFound != setTxids.size())
301  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Not all transactions found in specified or retrieved block");
302 
303  CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS);
304  CMerkleBlock mb(block, setTxids);
305  ssMB << mb;
306  std::string strHex = HexStr(ssMB.begin(), ssMB.end());
307  return strHex;
308 }
309 
311 {
312  if (request.fHelp || request.params.size() != 1)
313  throw std::runtime_error(
314  "verifytxoutproof \"proof\"\n"
315  "\nVerifies that a proof points to a transaction in a block, returning the transaction it commits to\n"
316  "and throwing an RPC error if the block is not in our best chain\n"
317  "\nArguments:\n"
318  "1. \"proof\" (string, required) The hex-encoded proof generated by gettxoutproof\n"
319  "\nResult:\n"
320  "[\"txid\"] (array, strings) The txid(s) which the proof commits to, or empty array if the proof is invalid\n"
321  );
322 
323  CDataStream ssMB(ParseHexV(request.params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS);
324  CMerkleBlock merkleBlock;
325  ssMB >> merkleBlock;
326 
328 
329  std::vector<uint256> vMatch;
330  std::vector<unsigned int> vIndex;
331  if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) != merkleBlock.header.hashMerkleRoot)
332  return res;
333 
334  LOCK(cs_main);
335 
336  if (!mapBlockIndex.count(merkleBlock.header.GetHash()) || !chainActive.Contains(mapBlockIndex[merkleBlock.header.GetHash()]))
337  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain");
338 
339  for (const uint256& hash : vMatch)
340  res.push_back(hash.GetHex());
341  return res;
342 }
343 
345 {
346  if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
347  throw std::runtime_error(
348  "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":(amount or object),\"data\":\"hex\",...} ( locktime ) ( replaceable )\n"
349  "\nCreate a transaction spending the given inputs and creating new outputs.\n"
350  "Outputs are addresses (paired with a RVN amount, data or object specifying an asset operation) or data.\n"
351  "Returns hex-encoded raw transaction.\n"
352  "Note that the transaction's inputs are not signed, and\n"
353  "it is not stored in the wallet or transmitted to the network.\n"
354 
355  "\nPaying for Asset Operations:\n"
356  " Some operations require an amount of RVN to be sent to a burn address:\n"
357  " transfer: 0\n"
358  " issue: 500 to Issue Burn Address\n"
359  " issue_unique 5 to Issue Unique Burn Address\n"
360  " reissue: 100 to Reissue Burn Address\n"
361  " transferwithmessage: 0\n"
362 
363  "\nOwnership:\n"
364  " These operations require an ownership token input for the asset being operated upon:\n"
365  " issue_unique\n"
366  " reissue\n"
367 
368  "\nOutput Ordering:\n"
369  " Asset operations require the following:\n"
370  " 1) All coin outputs come first (including the burn output).\n"
371  " 2) The owner token change output comes next (if required).\n"
372  " 3) An issue, issue_unique, reissue or any number of transfers comes last\n"
373  " (different types can't be mixed in a single transaction).\n"
374 
375  "\nArguments:\n"
376  "1. \"inputs\" (array, required) A json array of json objects\n"
377  " [\n"
378  " {\n"
379  " \"txid\":\"id\", (string, required) The transaction id\n"
380  " \"vout\":n, (number, required) The output number\n"
381  " \"sequence\":n (number, optional) The sequence number\n"
382  " } \n"
383  " ,...\n"
384  " ]\n"
385  "2. \"outputs\" (object, required) a json object with outputs\n"
386  " {\n"
387  " \"address\": (string, required) The destination raven address. Each output must have a different address.\n"
388  " x.xxx (number or string, required) The RVN amount\n"
389  " or\n"
390  " { (object) A json object of assets to send\n"
391  " \"transfer\":\n"
392  " {\n"
393  " \"asset-name\": (string, required) asset name\n"
394  " asset-quantity (number, required) the number of raw units to transfer\n"
395  " ,...\n"
396  " }\n"
397  " }\n"
398  " or\n"
399  " { (object) A json object of describing the transfer and message contents to send\n"
400  " \"transferwithmessage\":\n"
401  " {\n"
402  " \"asset-name\": (string, required) asset name\n"
403  " asset-quantity, (number, required) the number of raw units to transfer\n"
404  " \"message\":\"hash\", (string, required) ipfs hash or a txid hash\n"
405  " \"expire_time\": n (number, required) utc time in seconds to expire the message\n"
406  " }\n"
407  " }\n"
408  " or\n"
409  " { (object) A json object describing new assets to issue\n"
410  " \"issue\":\n"
411  " {\n"
412  " \"asset_name\":\"asset-name\", (string, required) new asset name\n"
413  " \"asset_quantity\":n, (number, required) the number of raw units to issue\n"
414  " \"units\":[1-8], (number, required) display units, between 1 (integral) to 8 (max precision)\n"
415  " \"reissuable\":[0-1], (number, required) 1=reissuable asset\n"
416  " \"has_ipfs\":[0-1], (number, required) 1=passing ipfs_hash\n"
417  " \"ipfs_hash\":\"hash\" (string, optional) an ipfs hash for discovering asset metadata\n"
418  " }\n"
419  " }\n"
420  " or\n"
421  " { (object) A json object describing new unique assets to issue\n"
422  " \"issue_unique\":\n"
423  " {\n"
424  " \"root_name\":\"root-name\", (string, required) name of the asset the unique asset(s) are being issued under\n"
425  " \"asset_tags\":[\"asset_tag\", ...], (array, required) the unique tag for each asset which is to be issued\n"
426  " \"ipfs_hashes\":[\"hash\", ...], (array, optional) ipfs hashes corresponding to each supplied tag (should be same size as \"asset_tags\")\n"
427  " }\n"
428  " }\n"
429  " or\n"
430  " { (object) A json object describing follow-on asset issue. Requires matching ownership input.\n"
431  " \"reissue\":\n"
432  " {\n"
433  " \"asset_name\":\"asset-name\", (string, required) name of asset to be reissued\n"
434  " \"asset_quantity\":n, (number, required) the number of raw units to issue\n"
435  " \"reissuable\":[0-1], (number, optional) default is 1, 1=reissuable asset\n"
436  " \"ipfs_hash\":\"hash\", (string, optional) An ipfs hash for discovering asset metadata, Overrides the current ipfs hash if given\n"
437  " \"owner_change_address\" (string, optional) the address where the owner token will be sent to. If not given, it will be sent to the output address\n"
438  " }\n"
439  " }\n"
440  " or\n"
441  " { (object) A json object describing how restricted asset to issue\n"
442  " \"issue_restricted\":\n"
443  " {\n"
444  " \"asset_name\":\"asset-name\",(string, required) new asset name\n"
445  " \"asset_quantity\":n, (number, required) the number of raw units to issue\n"
446  " \"verifier_string\":\"text\", (string, required) the verifier string to be used for a restricted asset transfer verification\n"
447  " \"units\":[1-8], (number, required) display units, between 1 (integral) to 8 (max precision)\n"
448  " \"reissuable\":[0-1], (number, required) 1=reissuable asset\n"
449  " \"has_ipfs\":[0-1], (number, required) 1=passing ipfs_hash\n"
450  " \"ipfs_hash\":\"hash\", (string, optional) an ipfs hash for discovering asset metadata\n"
451  " \"owner_change_address\" (string, optional) the address where the owner token will be sent to. If not given, it will be sent to the output address\n"
452  " }\n"
453  " }\n"
454  " or\n"
455  " \"data\": \"hex\" (string, required) The key is \"data\", the value is hex encoded data\n"
456  " ,...\n"
457  " }\n"
458  "3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n"
459 // "4. replaceable (boolean, optional, default=false) Marks this transaction as BIP125 replaceable.\n"
460 // " Allows this transaction to be replaced by a transaction with higher fees.\n"
461 // " If provided, it is an error if explicit sequence numbers are incompatible.\n"
462  "\nResult:\n"
463  "\"transaction\" (string) hex string of the transaction\n"
464 
465  "\nExamples:\n"
466  + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"mycoin\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":0.01}\"")
467  + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"mycoin\\\",\\\"vout\\\":0}]\" \"{\\\"data\\\":\\\"00010203\\\"}\"")
468  + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"mycoin\\\",\\\"vout\\\":0}]\" \"{\\\"RXissueAssetXXXXXXXXXXXXXXXXXhhZGt\\\":500,\\\"change_address\\\":change_amount,\\\"issuer_address\\\":{\\\"issue\\\":{\\\"asset_name\\\":\\\"MYASSET\\\",\\\"asset_quantity\\\":1000000,\\\"units\\\":1,\\\"reissuable\\\":0,\\\"has_ipfs\\\":1,\\\"ipfs_hash\\\":\\\"43f81c6f2c0593bde5a85e09ae662816eca80797\\\"}}}\"")
469  + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"mycoin\\\",\\\"vout\\\":0}]\" \"{\\\"RXissueRestrictedXXXXXXXXXXXXzJZ1q\\\":1500,\\\"change_address\\\":change_amount,\\\"issuer_address\\\":{\\\"issue_restricted\\\":{\\\"asset_name\\\":\\\"$MYASSET\\\",\\\"asset_quantity\\\":1000000,\\\"verifier_string\\\":\\\"#TAG & !KYC\\\",\\\"units\\\":1,\\\"reissuable\\\":0,\\\"has_ipfs\\\":1,\\\"ipfs_hash\\\":\\\"43f81c6f2c0593bde5a85e09ae662816eca80797\\\"}}}\"")
470  + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"mycoin\\\",\\\"vout\\\":0}]\" \"{\\\"RXissueUniqueAssetXXXXXXXXXXWEAe58\\\":20,\\\"change_address\\\":change_amount,\\\"issuer_address\\\":{\\\"issue_unique\\\":{\\\"root_name\\\":\\\"MYASSET\\\",\\\"asset_tags\\\":[\\\"ALPHA\\\",\\\"BETA\\\"],\\\"ipfs_hashes\\\":[\\\"43f81c6f2c0593bde5a85e09ae662816eca80797\\\",\\\"43f81c6f2c0593bde5a85e09ae662816eca80797\\\"]}}}\"")
471  + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"mycoin\\\",\\\"vout\\\":0},{\\\"txid\\\":\\\"myasset\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":{\\\"transfer\\\":{\\\"MYASSET\\\":50}}}\"")
472  + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"mycoin\\\",\\\"vout\\\":0},{\\\"txid\\\":\\\"myasset\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":{\\\"transferwithmessage\\\":{\\\"MYASSET\\\":50,\\\"message\\\":\\\"hash\\\",\\\"expire_time\\\": utc_time}}}\"")
473  + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"mycoin\\\",\\\"vout\\\":0},{\\\"txid\\\":\\\"myownership\\\",\\\"vout\\\":0}]\" \"{\\\"issuer_address\\\":{\\\"reissue\\\":{\\\"asset_name\\\":\\\"MYASSET\\\",\\\"asset_quantity\\\":2000000}}}\"")
474  + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"mycoin\\\",\\\"vout\\\":0}]\", \"{\\\"data\\\":\\\"00010203\\\"}\"")
475  );
476 
477  RPCTypeCheck(request.params, {UniValue::VARR, UniValue::VOBJ, UniValue::VNUM}, true);
478  if (request.params[0].isNull() || request.params[1].isNull())
479  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, arguments 1 and 2 must be non-null");
480 
481  UniValue inputs = request.params[0].get_array();
482  UniValue sendTo = request.params[1].get_obj();
483 
484  CMutableTransaction rawTx;
485 
486  if (!request.params[2].isNull()) {
487  int64_t nLockTime = request.params[2].get_int64();
488  if (nLockTime < 0 || nLockTime > std::numeric_limits<uint32_t>::max())
489  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, locktime out of range");
490  rawTx.nLockTime = nLockTime;
491  }
492 
493 // bool rbfOptIn = request.params[3].isTrue();
494 
495  for (unsigned int idx = 0; idx < inputs.size(); idx++) {
496  const UniValue& input = inputs[idx];
497  const UniValue& o = input.get_obj();
498 
499  uint256 txid = ParseHashO(o, "txid");
500 
501  const UniValue& vout_v = find_value(o, "vout");
502  if (!vout_v.isNum())
503  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");
504  int nOutput = vout_v.get_int();
505  if (nOutput < 0)
506  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
507 
508  uint32_t nSequence;
509 // if (rbfOptIn) {
510 // nSequence = MAX_BIP125_RBF_SEQUENCE;
511 // } else if (rawTx.nLockTime) {
512 // nSequence = std::numeric_limits<uint32_t>::max() - 1;
513 // } else {
514 // nSequence = std::numeric_limits<uint32_t>::max();
515 // }
516 
517  if (rawTx.nLockTime) {
518  nSequence = std::numeric_limits<uint32_t>::max() - 1;
519  } else {
520  nSequence = std::numeric_limits<uint32_t>::max();
521  }
522 
523  // set the sequence number if passed in the parameters object
524  const UniValue& sequenceObj = find_value(o, "sequence");
525  if (sequenceObj.isNum()) {
526  int64_t seqNr64 = sequenceObj.get_int64();
527  if (seqNr64 < 0 || seqNr64 > std::numeric_limits<uint32_t>::max()) {
528  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, sequence number is out of range");
529  } else {
530  nSequence = (uint32_t)seqNr64;
531  }
532  }
533 
534  CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence);
535 
536  rawTx.vin.push_back(in);
537  }
538 
539  auto currentActiveAssetCache = GetCurrentAssetCache();
540 
541  std::set<CTxDestination> destinations;
542  std::vector<std::string> addrList = sendTo.getKeys();
543  for (const std::string& name_ : addrList) {
544 
545  if (name_ == "data") {
546  std::vector<unsigned char> data = ParseHexV(sendTo[name_].getValStr(),"Data");
547 
548  CTxOut out(0, CScript() << OP_RETURN << data);
549  rawTx.vout.push_back(out);
550  } else {
551  CTxDestination destination = DecodeDestination(name_);
552  if (!IsValidDestination(destination)) {
553  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Raven address: ") + name_);
554  }
555 
556  if (!destinations.insert(destination).second) {
557  throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + name_);
558  }
559 
560  CScript scriptPubKey = GetScriptForDestination(destination);
561  CScript ownerPubKey = GetScriptForDestination(destination);
562 
563 
564  if (sendTo[name_].type() == UniValue::VNUM || sendTo[name_].type() == UniValue::VSTR) {
565  CAmount nAmount = AmountFromValue(sendTo[name_]);
566  CTxOut out(nAmount, scriptPubKey);
567  rawTx.vout.push_back(out);
568  }
570  else if (sendTo[name_].type() == UniValue::VOBJ) {
571  auto asset_ = sendTo[name_].get_obj();
572  auto assetKey_ = asset_.getKeys()[0];
573 
574  if (assetKey_ == "issue")
575  {
576  if (asset_[0].type() != UniValue::VOBJ)
577  throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, the format must follow { \"issue\": {\"key\": value}, ...}"));
578 
579  // Get the asset data object from the json
580  auto assetData = asset_.getValues()[0].get_obj();
581 
583  const UniValue& asset_name = find_value(assetData, "asset_name");
584  if (!asset_name.isStr())
585  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing asset data for key: asset_name");
586 
587  const UniValue& asset_quantity = find_value(assetData, "asset_quantity");
588  if (!asset_quantity.isNum())
589  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing asset data for key: asset_quantity");
590 
591  const UniValue& units = find_value(assetData, "units");
592  if (!units.isNum())
593  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing asset metadata for key: units");
594 
595  const UniValue& reissuable = find_value(assetData, "reissuable");
596  if (!reissuable.isNum())
597  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing asset metadata for key: reissuable");
598 
599  const UniValue& has_ipfs = find_value(assetData, "has_ipfs");
600  if (!has_ipfs.isNum())
601  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing asset metadata for key: has_ipfs");
602 
603  UniValue ipfs_hash = "";
604  if (has_ipfs.get_int() == 1) {
605  ipfs_hash = find_value(assetData, "ipfs_hash");
606  if (!ipfs_hash.isStr())
607  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing asset metadata for key: has_ipfs");
608  }
609 
610  if (IsAssetNameAnRestricted(asset_name.get_str()))
611  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, asset_name can't be a restricted asset name. Please use issue_restricted with the correct parameters");
612 
613  CAmount nAmount = AmountFromValue(asset_quantity);
614 
615  // Create a new asset
616  CNewAsset asset(asset_name.get_str(), nAmount, units.get_int(), reissuable.get_int(), has_ipfs.get_int(), DecodeAssetData(ipfs_hash.get_str()));
617 
618  // Verify that data
619  std::string strError = "";
620  if (!ContextualCheckNewAsset(currentActiveAssetCache, asset, strError)) {
621  throw JSONRPCError(RPC_INVALID_PARAMETER, strError);
622  }
623 
624  // Construct the asset transaction
625  asset.ConstructTransaction(scriptPubKey);
626 
627  AssetType type;
628  if (IsAssetNameValid(asset.strName, type)) {
629  if (type != AssetType::UNIQUE && type != AssetType::MSGCHANNEL) {
630  asset.ConstructOwnerTransaction(ownerPubKey);
631 
632  // Push the scriptPubKey into the vouts.
633  CTxOut ownerOut(0, ownerPubKey);
634  rawTx.vout.push_back(ownerOut);
635  }
636  } else {
637  throw JSONRPCError(RPC_INVALID_PARAMETER, ("Invalid parameter, invalid asset name"));
638  }
639 
640  // Push the scriptPubKey into the vouts.
641  CTxOut out(0, scriptPubKey);
642  rawTx.vout.push_back(out);
643 
644  }
645  else if (assetKey_ == "issue_unique")
646  {
647  if (asset_[0].type() != UniValue::VOBJ)
648  throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, the format must follow { \"issue_unique\": {\"root_name\": value}, ...}"));
649 
650  // Get the asset data object from the json
651  auto assetData = asset_.getValues()[0].get_obj();
652 
654  const UniValue& root_name = find_value(assetData, "root_name");
655  if (!root_name.isStr())
656  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing asset data for key: root_name");
657 
658  const UniValue& asset_tags = find_value(assetData, "asset_tags");
659  if (!asset_tags.isArray() || asset_tags.size() < 1)
660  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing asset data for key: asset_tags");
661 
662  const UniValue& ipfs_hashes = find_value(assetData, "ipfs_hashes");
663  if (!ipfs_hashes.isNull()) {
664  if (!ipfs_hashes.isArray() || ipfs_hashes.size() != asset_tags.size()) {
665  if (!ipfs_hashes.isNum())
667  "Invalid parameter, missing asset metadata for key: units");
668  }
669  }
670 
671  // Create the scripts for the change of the ownership token
672  CScript scriptTransferOwnerAsset = GetScriptForDestination(destination);
673  CAssetTransfer assetTransfer(root_name.get_str() + OWNER_TAG, OWNER_ASSET_AMOUNT);
674  assetTransfer.ConstructTransaction(scriptTransferOwnerAsset);
675 
676  // Create the CTxOut for the owner token
677  CTxOut out(0, scriptTransferOwnerAsset);
678  rawTx.vout.push_back(out);
679 
680  // Create the assets
681  for (int i = 0; i < (int)asset_tags.size(); i++) {
682 
683  // Create a new asset
684  CNewAsset asset;
685  if (ipfs_hashes.isNull()) {
686  asset = CNewAsset(GetUniqueAssetName(root_name.get_str(), asset_tags[i].get_str()),
688  } else {
689  asset = CNewAsset(GetUniqueAssetName(root_name.get_str(), asset_tags[i].get_str()),
691  1, DecodeAssetData(ipfs_hashes[i].get_str()));
692  }
693 
694  // Verify that data
695  std::string strError = "";
696  if (!ContextualCheckNewAsset(currentActiveAssetCache, asset, strError))
697  throw JSONRPCError(RPC_INVALID_PARAMETER, strError);
698 
699  // Construct the asset transaction
700  scriptPubKey = GetScriptForDestination(destination);
701  asset.ConstructTransaction(scriptPubKey);
702 
703  // Push the scriptPubKey into the vouts.
704  CTxOut out(0, scriptPubKey);
705  rawTx.vout.push_back(out);
706 
707  }
708  }
709  else if (assetKey_ == "reissue")
710  {
711  if (asset_[0].type() != UniValue::VOBJ)
712  throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, the format must follow { \"reissue\": {\"key\": value}, ...}"));
713 
714  // Get the asset data object from the json
715  auto reissueData = asset_.getValues()[0].get_obj();
716 
717  CReissueAsset reissueObj;
718 
720  const UniValue& asset_name = find_value(reissueData, "asset_name");
721  if (!asset_name.isStr())
722  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing reissue data for key: asset_name");
723 
724  const UniValue& asset_quantity = find_value(reissueData, "asset_quantity");
725  if (!asset_quantity.isNum())
726  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing reissue data for key: asset_quantity");
727 
728  const UniValue& reissuable = find_value(reissueData, "reissuable");
729  if (!reissuable.isNull()) {
730  if (!reissuable.isNum())
732  "Invalid parameter, missing reissue metadata for key: reissuable");
733 
734  int nReissuable = reissuable.get_int();
735  if (nReissuable > 1 || nReissuable < 0)
737  "Invalid parameter, reissuable data must be a 0 or 1");
738 
739  reissueObj.nReissuable = int8_t(nReissuable);
740  }
741 
742  const UniValue& ipfs_hash = find_value(reissueData, "ipfs_hash");
743  if (!ipfs_hash.isNull()) {
744  if (!ipfs_hash.isStr())
746  "Invalid parameter, missing reissue metadata for key: ipfs_hash");
747  reissueObj.strIPFSHash = DecodeAssetData(ipfs_hash.get_str());
748  }
749 
750  bool fHasOwnerChange = false;
751  const UniValue& owner_change_address = find_value(reissueData, "owner_change_address");
752  if (!owner_change_address.isNull()) {
753  if (!owner_change_address.isStr())
755  "Invalid parameter, owner_change_address must be a string");
756  fHasOwnerChange = true;
757  }
758 
759  if (fHasOwnerChange && !IsValidDestinationString(owner_change_address.get_str()))
760  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, owner_change_address is not a valid Ravencoin address");
761 
762  if (IsAssetNameAnRestricted(asset_name.get_str()))
763  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, asset_name can't be a restricted asset name. Please use reissue_restricted with the correct parameters");
764 
765  // Add the received data into the reissue object
766  reissueObj.strName = asset_name.get_str();
767  reissueObj.nAmount = AmountFromValue(asset_quantity);
768 
769  // Validate the the object is valid
770  std::string strError;
771  if (!ContextualCheckReissueAsset(currentActiveAssetCache, reissueObj, strError))
772  throw JSONRPCError(RPC_INVALID_PARAMETER, strError);
773 
774  // Create the scripts for the change of the ownership token
775  CScript owner_asset_transfer_script;
776  if (fHasOwnerChange)
777  owner_asset_transfer_script = GetScriptForDestination(DecodeDestination(owner_change_address.get_str()));
778  else
779  owner_asset_transfer_script = GetScriptForDestination(destination);
780 
781  CAssetTransfer transfer_owner(asset_name.get_str() + OWNER_TAG, OWNER_ASSET_AMOUNT);
782  transfer_owner.ConstructTransaction(owner_asset_transfer_script);
783 
784  // Create the scripts for the reissued assets
785  CScript scriptReissueAsset = GetScriptForDestination(destination);
786  reissueObj.ConstructTransaction(scriptReissueAsset);
787 
788  // Create the CTxOut for the owner token
789  CTxOut out(0, owner_asset_transfer_script);
790  rawTx.vout.push_back(out);
791 
792  // Create the CTxOut for the reissue asset
793  CTxOut out2(0, scriptReissueAsset);
794  rawTx.vout.push_back(out2);
795 
796  } else if (assetKey_ == "transfer") {
797  if (asset_[0].type() != UniValue::VOBJ)
798  throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, the format must follow { \"transfer\": {\"asset_name\": amount, ...} }"));
799 
800  UniValue transferData = asset_.getValues()[0].get_obj();
801 
802  auto keys = transferData.getKeys();
803 
804  if (keys.size() == 0)
805  throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, the format must follow { \"transfer\": {\"asset_name\": amount, ...} }"));
806 
807  UniValue asset_quantity;
808  for (auto asset_name : keys) {
809  asset_quantity = find_value(transferData, asset_name);
810 
811  if (!asset_quantity.isNum())
812  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing or invalid quantity");
813 
814  CAmount nAmount = AmountFromValue(asset_quantity);
815 
816  // Create a new transfer
817  CAssetTransfer transfer(asset_name, nAmount);
818 
819  // Verify
820  std::string strError = "";
821  if (!transfer.IsValid(strError)) {
822  throw JSONRPCError(RPC_INVALID_PARAMETER, strError);
823  }
824 
825  // Construct transaction
826  CScript scriptPubKey = GetScriptForDestination(destination);
827  transfer.ConstructTransaction(scriptPubKey);
828 
829  // Push into vouts
830  CTxOut out(0, scriptPubKey);
831  rawTx.vout.push_back(out);
832  }
833  } else if (assetKey_ == "transferwithmessage") {
834  if (asset_[0].type() != UniValue::VOBJ)
835  throw JSONRPCError(RPC_INVALID_PARAMETER, std::string(
836  "Invalid parameter, the format must follow { \"transferwithmessage\": {\"asset_name\": amount, \"message\": messagehash, \"expire_time\": utc_time} }"));
837 
838  UniValue transferData = asset_.getValues()[0].get_obj();
839 
840  auto keys = transferData.getKeys();
841 
842  if (keys.size() == 0)
843  throw JSONRPCError(RPC_INVALID_PARAMETER, std::string(
844  "Invalid parameter, the format must follow { \"transferwithmessage\": {\"asset_name\": amount, \"message\": messagehash, \"expire_time\": utc_time} }"));
845 
846  UniValue asset_quantity;
847  std::string asset_name = keys[0];
848 
849  if (!IsAssetNameValid(asset_name)) {
851  "Invalid parameter, missing valid asset name to transferwithmessage");
852 
853  const UniValue &asset_quantity = find_value(transferData, asset_name);
854  if (!asset_quantity.isNum())
855  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing or invalid quantity");
856 
857  const UniValue &message = find_value(transferData, "message");
858  if (!message.isStr())
860  "Invalid parameter, missing reissue data for key: message");
861 
862  const UniValue &expire_time = find_value(transferData, "expire_time");
863  if (!expire_time.isNum())
865  "Invalid parameter, missing reissue data for key: expire_time");
866 
867  CAmount nAmount = AmountFromValue(asset_quantity);
868 
869  // Create a new transfer
870  CAssetTransfer transfer(asset_name, nAmount, DecodeAssetData(message.get_str()),
871  expire_time.get_int64());
872 
873  // Verify
874  std::string strError = "";
875  if (!transfer.IsValid(strError)) {
876  throw JSONRPCError(RPC_INVALID_PARAMETER, strError);
877  }
878 
879  // Construct transaction
880  CScript scriptPubKey = GetScriptForDestination(destination);
881  transfer.ConstructTransaction(scriptPubKey);
882 
883  // Push into vouts
884  CTxOut out(0, scriptPubKey);
885  rawTx.vout.push_back(out);
886  }
887  } else if (assetKey_ == "issue_restricted") {
888  if (asset_[0].type() != UniValue::VOBJ)
889  throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, the format must follow { \"issue_restricted\": {\"key\": value}, ...}"));
890 
891  // Get the asset data object from the json
892  auto assetData = asset_.getValues()[0].get_obj();
893 
895  const UniValue& asset_name = find_value(assetData, "asset_name");
896  if (!asset_name.isStr())
897  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing asset data for key: asset_name");
898 
899  const UniValue& asset_quantity = find_value(assetData, "asset_quantity");
900  if (!asset_quantity.isNum())
901  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing asset data for key: asset_quantity");
902 
903  const UniValue& verifier_string = find_value(assetData, "verifier_string");
904  if (!verifier_string.isStr())
905  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing asset_data for key: verifier_string");
906 
907  const UniValue& units = find_value(assetData, "units");
908  if (!units.isNum())
909  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing asset metadata for key: units");
910 
911  const UniValue& reissuable = find_value(assetData, "reissuable");
912  if (!reissuable.isNum())
913  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing asset metadata for key: reissuable");
914 
915  const UniValue& has_ipfs = find_value(assetData, "has_ipfs");
916  if (!has_ipfs.isNum())
917  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing asset metadata for key: has_ipfs");
918 
919  bool fHasOwnerChange = false;
920  const UniValue& owner_change_address = find_value(assetData, "owner_change_address");
921  if (!owner_change_address.isNull()) {
922  if (!owner_change_address.isStr())
924  "Invalid parameter, owner_change_address must be a string");
925  fHasOwnerChange = true;
926  }
927 
928  if (fHasOwnerChange && !IsValidDestinationString(owner_change_address.get_str()))
929  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, owner_change_address is not a valid Ravencoin address");
930 
931  UniValue ipfs_hash = "";
932  if (has_ipfs.get_int() == 1) {
933  ipfs_hash = find_value(assetData, "ipfs_hash");
934  if (!ipfs_hash.isStr())
935  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing asset metadata for key: has_ipfs");
936  }
937 
938  std::string strAssetName = asset_name.get_str();
939 
940  if (!IsAssetNameAnRestricted(strAssetName))
941  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, asset_name must be a restricted asset name. e.g $ASSET_NAME");
942 
943  CAmount nAmount = AmountFromValue(asset_quantity);
944 
945  // Strip the white spaces from the verifier string
946  std::string strippedVerifierString = GetStrippedVerifierString(verifier_string.get_str());
947 
948  // Check the restricted asset destination address, and make sure it validates with the verifier string
949  std::string strError = "";
950  if (!ContextualCheckVerifierString(currentActiveAssetCache, strippedVerifierString, EncodeDestination(destination), strError, false))
951  throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parmeter, verifier string is not. Please check the syntax. Error Msg - " + strError));
952 
953 
954  // Create a new asset
955  CNewAsset asset(strAssetName, nAmount, units.get_int(), reissuable.get_int(), has_ipfs.get_int(), DecodeAssetData(ipfs_hash.get_str()));
956 
957  // Verify the new asset data
958  if (!ContextualCheckNewAsset(currentActiveAssetCache, asset, strError)) {
959  throw JSONRPCError(RPC_INVALID_PARAMETER, strError);
960  }
961 
962  // Construct the restricted issuance script
963  CScript restricted_issuance_script = GetScriptForDestination(destination);
964  asset.ConstructTransaction(restricted_issuance_script);
965 
966  // Construct the owner change script
967  CScript owner_asset_transfer_script;
968  if (fHasOwnerChange)
969  owner_asset_transfer_script = GetScriptForDestination(DecodeDestination(owner_change_address.get_str()));
970  else
971  owner_asset_transfer_script = GetScriptForDestination(destination);
972 
973  CAssetTransfer transfer_owner(strAssetName.substr(1, strAssetName.size()) + OWNER_TAG, OWNER_ASSET_AMOUNT);
974  transfer_owner.ConstructTransaction(owner_asset_transfer_script);
975 
976  // Construct the verifier string script
977  CScript verifier_string_script;
978  CNullAssetTxVerifierString verifierString(strippedVerifierString);
979  verifierString.ConstructTransaction(verifier_string_script);
980 
981  // Create the CTxOut for each script we need to issue a restricted asset
982  CTxOut resissue(0, restricted_issuance_script);
983  CTxOut owner_change(0, owner_asset_transfer_script);
984  CTxOut verifier(0, verifier_string_script);
985 
986  // Push the scriptPubKey into the vouts.
987  rawTx.vout.push_back(verifier);
988  rawTx.vout.push_back(owner_change);
989  rawTx.vout.push_back(resissue);
990 
991  } else {
992  throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, unknown output type (should be 'issue', 'issue_restricted', 'reissue', 'transfer' or 'transferwithmessage'): " + assetKey_));
993  }
994  } else {
995  throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, Output must be of the type object"));
996  }
998  }
999  }
1000 
1001 // if (!request.params[3].isNull() && rbfOptIn != SignalsOptInRBF(rawTx)) {
1002 // throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter combination: Sequence number(s) contradict replaceable option");
1003 // }
1004 
1005  return EncodeHexTx(rawTx);
1006 }
1007 
1009 {
1010  if (request.fHelp || request.params.size() != 1)
1011  throw std::runtime_error(
1012  "decoderawtransaction \"hexstring\"\n"
1013  "\nReturn a JSON object representing the serialized, hex-encoded transaction.\n"
1014 
1015  "\nArguments:\n"
1016  "1. \"hexstring\" (string, required) The transaction hex string\n"
1017 
1018  "\nResult:\n"
1019  "{\n"
1020  " \"txid\" : \"id\", (string) The transaction id\n"
1021  " \"hash\" : \"id\", (string) The transaction hash (differs from txid for witness transactions)\n"
1022  " \"size\" : n, (numeric) The transaction size\n"
1023  " \"vsize\" : n, (numeric) The virtual transaction size (differs from size for witness transactions)\n"
1024  " \"version\" : n, (numeric) The version\n"
1025  " \"locktime\" : ttt, (numeric) The lock time\n"
1026  " \"vin\" : [ (array of json objects)\n"
1027  " {\n"
1028  " \"txid\": \"id\", (string) The transaction id\n"
1029  " \"vout\": n, (numeric) The output number\n"
1030  " \"scriptSig\": { (json object) The script\n"
1031  " \"asm\": \"asm\", (string) asm\n"
1032  " \"hex\": \"hex\" (string) hex\n"
1033  " },\n"
1034  " \"txinwitness\": [\"hex\", ...] (array of string) hex-encoded witness data (if any)\n"
1035  " \"sequence\": n (numeric) The script sequence number\n"
1036  " }\n"
1037  " ,...\n"
1038  " ],\n"
1039  " \"vout\" : [ (array of json objects)\n"
1040  " {\n"
1041  " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n"
1042  " \"n\" : n, (numeric) index\n"
1043  " \"scriptPubKey\" : { (json object)\n"
1044  " \"asm\" : \"asm\", (string) the asm\n"
1045  " \"hex\" : \"hex\", (string) the hex\n"
1046  " \"reqSigs\" : n, (numeric) The required sigs\n"
1047  " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
1048  " \"addresses\" : [ (json array of string)\n"
1049  " \"12tvKAXCxZjSmdNbao16dKXC8tRWfcF5oc\" (string) raven address\n"
1050  " ,...\n"
1051  " ]\n"
1052  " }\n"
1053  " }\n"
1054  " ,...\n"
1055  " ],\n"
1056  "}\n"
1057 
1058  "\nExamples:\n"
1059  + HelpExampleCli("decoderawtransaction", "\"hexstring\"")
1060  + HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
1061  );
1062 
1063  LOCK(cs_main);
1064  RPCTypeCheck(request.params, {UniValue::VSTR});
1065 
1066  CMutableTransaction mtx;
1067 
1068  if (!DecodeHexTx(mtx, request.params[0].get_str(), true))
1069  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
1070 
1071  UniValue result(UniValue::VOBJ);
1072  TxToUniv(CTransaction(std::move(mtx)), uint256(), result, false);
1073 
1074  return result;
1075 }
1076 
1078 {
1079  if (request.fHelp || request.params.size() != 1)
1080  throw std::runtime_error(
1081  "decodescript \"hexstring\"\n"
1082  "\nDecode a hex-encoded script.\n"
1083  "\nArguments:\n"
1084  "1. \"hexstring\" (string) the hex encoded script\n"
1085  "\nResult:\n"
1086  "{\n"
1087  " \"asm\":\"asm\", (string) Script public key\n"
1088  " \"hex\":\"hex\", (string) hex encoded public key\n"
1089  " \"type\":\"type\", (string) The output type\n"
1090  " \"reqSigs\": n, (numeric) The required signatures\n"
1091  " \"addresses\": [ (json array of string)\n"
1092  " \"address\" (string) raven address\n"
1093  " ,...\n"
1094  " ],\n"
1095  " \"p2sh\":\"address\", (string) address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH).\n"
1096  " \"(The following only appears if the script is an asset script)\n"
1097  " \"asset_name\":\"name\", (string) Name of the asset.\n"
1098  " \"amount\":\"x.xx\", (numeric) The amount of assets interacted with.\n"
1099  " \"units\": n, (numeric) The units of the asset. (Only appears in the type (new_asset))\n"
1100  " \"reissuable\": true|false, (boolean) If this asset is reissuable. (Only appears in type (new_asset|reissue_asset))\n"
1101  " \"hasIPFS\": true|false, (boolean) If this asset has an IPFS hash. (Only appears in type (new_asset if hasIPFS is true))\n"
1102  " \"ipfs_hash\": \"hash\", (string) The ipfs hash for the new asset. (Only appears in type (new_asset))\n"
1103  " \"new_ipfs_hash\":\"hash\", (string) If new ipfs hash (Only appears in type. (reissue_asset))\n"
1104  "}\n"
1105  "\nExamples:\n"
1106  + HelpExampleCli("decodescript", "\"hexstring\"")
1107  + HelpExampleRpc("decodescript", "\"hexstring\"")
1108  );
1109 
1110  RPCTypeCheck(request.params, {UniValue::VSTR});
1111 
1113  CScript script;
1114  if (request.params[0].get_str().size() > 0){
1115  std::vector<unsigned char> scriptData(ParseHexV(request.params[0], "argument"));
1116  script = CScript(scriptData.begin(), scriptData.end());
1117  } else {
1118  // Empty scripts are valid
1119  }
1120  ScriptPubKeyToUniv(script, r, false);
1121 
1122  UniValue type;
1123  type = find_value(r, "type");
1124 
1125  if (type.isStr() && type.get_str() != "scripthash") {
1126  // P2SH cannot be wrapped in a P2SH. If this script is already a P2SH,
1127  // don't return the address for a P2SH of the P2SH.
1128  r.push_back(Pair("p2sh", EncodeDestination(CScriptID(script))));
1129  }
1130 
1132  if (type.isStr() && type.get_str() == ASSET_TRANSFER_STRING) {
1133  if (!AreAssetsDeployed())
1134  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Assets are not active");
1135 
1137  std::string address;
1138 
1139  if (!TransferAssetFromScript(script, transfer, address))
1140  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Failed to deserialize the transfer asset script");
1141 
1142  r.push_back(Pair("asset_name", transfer.strName));
1143  r.push_back(Pair("amount", ValueFromAmount(transfer.nAmount)));
1144 
1145  } else if (type.isStr() && type.get_str() == ASSET_REISSUE_STRING) {
1146  if (!AreAssetsDeployed())
1147  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Assets are not active");
1148 
1150  std::string address;
1151 
1152  if (!ReissueAssetFromScript(script, reissue, address))
1153  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Failed to deserialize the reissue asset script");
1154 
1155  r.push_back(Pair("asset_name", reissue.strName));
1156  r.push_back(Pair("amount", ValueFromAmount(reissue.nAmount)));
1157 
1158  bool reissuable = reissue.nReissuable ? true : false;
1159  r.push_back(Pair("reissuable", reissuable));
1160 
1161  if (reissue.strIPFSHash != "")
1162  r.push_back(Pair("new_ipfs_hash", EncodeAssetData(reissue.strIPFSHash)));
1163 
1164  } else if (type.isStr() && type.get_str() == ASSET_NEW_STRING) {
1165  if (!AreAssetsDeployed())
1166  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Assets are not active");
1167 
1168  CNewAsset asset;
1169  std::string ownerAsset;
1170  std::string address;
1171 
1172  if(AssetFromScript(script, asset, address)) {
1173  r.push_back(Pair("asset_name", asset.strName));
1174  r.push_back(Pair("amount", ValueFromAmount(asset.nAmount)));
1175  r.push_back(Pair("units", asset.units));
1176 
1177  bool reissuable = asset.nReissuable ? true : false;
1178  r.push_back(Pair("reissuable", reissuable));
1179 
1180  bool hasIPFS = asset.nHasIPFS ? true : false;
1181  r.push_back(Pair("hasIPFS", hasIPFS));
1182 
1183  if (hasIPFS)
1184  r.push_back(Pair("ipfs_hash", EncodeAssetData(asset.strIPFSHash)));
1185  }
1186  else if (OwnerAssetFromScript(script, ownerAsset, address))
1187  {
1188  r.push_back(Pair("asset_name", ownerAsset));
1189  r.push_back(Pair("amount", ValueFromAmount(OWNER_ASSET_AMOUNT)));
1190  r.push_back(Pair("units", OWNER_UNITS));
1191  }
1192  else
1193  {
1194  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Failed to deserialize the new asset script");
1195  }
1196  } else {
1197 
1198  }
1201  return r;
1202 }
1203 
1205 static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std::string& strMessage)
1206 {
1207  UniValue entry(UniValue::VOBJ);
1208  entry.push_back(Pair("txid", txin.prevout.hash.ToString()));
1209  entry.push_back(Pair("vout", (uint64_t)txin.prevout.n));
1210  UniValue witness(UniValue::VARR);
1211  for (unsigned int i = 0; i < txin.scriptWitness.stack.size(); i++) {
1212  witness.push_back(HexStr(txin.scriptWitness.stack[i].begin(), txin.scriptWitness.stack[i].end()));
1213  }
1214  entry.push_back(Pair("witness", witness));
1215  entry.push_back(Pair("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
1216  entry.push_back(Pair("sequence", (uint64_t)txin.nSequence));
1217  entry.push_back(Pair("error", strMessage));
1218  vErrorsRet.push_back(entry);
1219 }
1220 
1222 {
1223 
1224  if (request.fHelp || request.params.size() != 1)
1225  throw std::runtime_error(
1226  "combinerawtransaction [\"hexstring\",...]\n"
1227  "\nCombine multiple partially signed transactions into one transaction.\n"
1228  "The combined transaction may be another partially signed transaction or a \n"
1229  "fully signed transaction."
1230 
1231  "\nArguments:\n"
1232  "1. \"txs\" (string) A json array of hex strings of partially signed transactions\n"
1233  " [\n"
1234  " \"hexstring\" (string) A transaction hash\n"
1235  " ,...\n"
1236  " ]\n"
1237 
1238  "\nResult:\n"
1239  "\"hex\" (string) The hex-encoded raw transaction with signature(s)\n"
1240 
1241  "\nExamples:\n"
1242  + HelpExampleCli("combinerawtransaction", "[\"myhex1\", \"myhex2\", \"myhex3\"]")
1243  );
1244 
1245 
1246  UniValue txs = request.params[0].get_array();
1247  std::vector<CMutableTransaction> txVariants(txs.size());
1248 
1249  for (unsigned int idx = 0; idx < txs.size(); idx++) {
1250  if (!DecodeHexTx(txVariants[idx], txs[idx].get_str(), true)) {
1251  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed for tx %d", idx));
1252  }
1253  }
1254 
1255  if (txVariants.empty()) {
1256  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transactions");
1257  }
1258 
1259  // mergedTx will end up with all the signatures; it
1260  // starts as a clone of the rawtx:
1261  CMutableTransaction mergedTx(txVariants[0]);
1262 
1263  // Fetch previous transactions (inputs):
1264  CCoinsView viewDummy;
1265  CCoinsViewCache view(&viewDummy);
1266  {
1267  LOCK(cs_main);
1268  LOCK(mempool.cs);
1269  CCoinsViewCache &viewChain = *pcoinsTip;
1270  CCoinsViewMemPool viewMempool(&viewChain, mempool);
1271  view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
1272 
1273  for (const CTxIn& txin : mergedTx.vin) {
1274  view.AccessCoin(txin.prevout); // Load entries from viewChain into view; can fail.
1275  }
1276 
1277  view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
1278  }
1279 
1280  // Use CTransaction for the constant parts of the
1281  // transaction to avoid rehashing.
1282  const CTransaction txConst(mergedTx);
1283  // Sign what we can:
1284  for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
1285  CTxIn& txin = mergedTx.vin[i];
1286  const Coin& coin = view.AccessCoin(txin.prevout);
1287  if (coin.IsSpent()) {
1288  throw JSONRPCError(RPC_VERIFY_ERROR, "Input not found or already spent");
1289  }
1290  const CScript& prevPubKey = coin.out.scriptPubKey;
1291  const CAmount& amount = coin.out.nValue;
1292 
1293  SignatureData sigdata;
1294 
1295  // ... and merge in other signatures:
1296  for (const CMutableTransaction& txv : txVariants) {
1297  if (txv.vin.size() > i) {
1298  sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(txv, i));
1299  }
1300  }
1301 
1302  UpdateTransaction(mergedTx, i, sigdata);
1303  }
1304 
1305  return EncodeHexTx(mergedTx);
1306 }
1307 
1309 {
1310 #ifdef ENABLE_WALLET
1311  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1312 #endif
1313 
1314  if (request.fHelp || request.params.size() < 1 || request.params.size() > 4)
1315  throw std::runtime_error(
1316  "signrawtransaction \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] [\"privatekey1\",...] sighashtype )\n"
1317  "\nSign inputs for raw transaction (serialized, hex-encoded).\n"
1318  "The second optional argument (may be null) is an array of previous transaction outputs that\n"
1319  "this transaction depends on but may not yet be in the block chain.\n"
1320  "The third optional argument (may be null) is an array of base58-encoded private\n"
1321  "keys that, if given, will be the only keys used to sign the transaction.\n"
1322 #ifdef ENABLE_WALLET
1323  + HelpRequiringPassphrase(pwallet) + "\n"
1324 #endif
1325 
1326  "\nArguments:\n"
1327  "1. \"hexstring\" (string, required) The transaction hex string\n"
1328  "2. \"prevtxs\" (string, optional) An json array of previous dependent transaction outputs\n"
1329  " [ (json array of json objects, or 'null' if none provided)\n"
1330  " {\n"
1331  " \"txid\":\"id\", (string, required) The transaction id\n"
1332  " \"vout\":n, (numeric, required) The output number\n"
1333  " \"scriptPubKey\": \"hex\", (string, required) script key\n"
1334  " \"redeemScript\": \"hex\", (string, required for P2SH or P2WSH) redeem script\n"
1335  " \"amount\": value (numeric, required) The amount spent\n"
1336  " }\n"
1337  " ,...\n"
1338  " ]\n"
1339  "3. \"privkeys\" (string, optional) A json array of base58-encoded private keys for signing\n"
1340  " [ (json array of strings, or 'null' if none provided)\n"
1341  " \"privatekey\" (string) private key in base58-encoding\n"
1342  " ,...\n"
1343  " ]\n"
1344  "4. \"sighashtype\" (string, optional, default=ALL) The signature hash type. Must be one of\n"
1345  " \"ALL\"\n"
1346  " \"NONE\"\n"
1347  " \"SINGLE\"\n"
1348  " \"ALL|ANYONECANPAY\"\n"
1349  " \"NONE|ANYONECANPAY\"\n"
1350  " \"SINGLE|ANYONECANPAY\"\n"
1351 
1352  "\nResult:\n"
1353  "{\n"
1354  " \"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n"
1355  " \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n"
1356  " \"errors\" : [ (json array of objects) Script verification errors (if there are any)\n"
1357  " {\n"
1358  " \"txid\" : \"hash\", (string) The hash of the referenced, previous transaction\n"
1359  " \"vout\" : n, (numeric) The index of the output to spent and used as input\n"
1360  " \"scriptSig\" : \"hex\", (string) The hex-encoded signature script\n"
1361  " \"sequence\" : n, (numeric) Script sequence number\n"
1362  " \"error\" : \"text\" (string) Verification or signing error related to the input\n"
1363  " }\n"
1364  " ,...\n"
1365  " ]\n"
1366  "}\n"
1367 
1368  "\nExamples:\n"
1369  + HelpExampleCli("signrawtransaction", "\"myhex\"")
1370  + HelpExampleRpc("signrawtransaction", "\"myhex\"")
1371  );
1372 
1373  ObserveSafeMode();
1374 #ifdef ENABLE_WALLET
1375  LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : nullptr);
1376 #else
1377  LOCK(cs_main);
1378 #endif
1379  RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VARR, UniValue::VSTR}, true);
1380 
1381  CMutableTransaction mtx;
1382  if (!DecodeHexTx(mtx, request.params[0].get_str(), true))
1383  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
1384 
1385  // Fetch previous transactions (inputs):
1386  CCoinsView viewDummy;
1387  CCoinsViewCache view(&viewDummy);
1388  {
1389  LOCK(mempool.cs);
1390  CCoinsViewCache &viewChain = *pcoinsTip;
1391  CCoinsViewMemPool viewMempool(&viewChain, mempool);
1392  view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
1393 
1394  for (const CTxIn& txin : mtx.vin) {
1395  view.AccessCoin(txin.prevout); // Load entries from viewChain into view; can fail.
1396  }
1397 
1398  view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
1399  }
1400 
1401  bool fGivenKeys = false;
1402  CBasicKeyStore tempKeystore;
1403  if (!request.params[2].isNull()) {
1404  fGivenKeys = true;
1405  UniValue keys = request.params[2].get_array();
1406  for (unsigned int idx = 0; idx < keys.size(); idx++) {
1407  UniValue k = keys[idx];
1408  CRavenSecret vchSecret;
1409  bool fGood = vchSecret.SetString(k.get_str());
1410  if (!fGood)
1411  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
1412  CKey key = vchSecret.GetKey();
1413  if (!key.IsValid())
1414  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
1415  tempKeystore.AddKey(key);
1416  }
1417  }
1418 #ifdef ENABLE_WALLET
1419  else if (pwallet) {
1420  EnsureWalletIsUnlocked(pwallet);
1421  }
1422 #endif
1423 
1424  // Add previous txouts given in the RPC call:
1425  if (!request.params[1].isNull()) {
1426  UniValue prevTxs = request.params[1].get_array();
1427  for (unsigned int idx = 0; idx < prevTxs.size(); idx++) {
1428  const UniValue& p = prevTxs[idx];
1429  if (!p.isObject())
1430  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}");
1431 
1432  UniValue prevOut = p.get_obj();
1433 
1434  RPCTypeCheckObj(prevOut,
1435  {
1436  {"txid", UniValueType(UniValue::VSTR)},
1437  {"vout", UniValueType(UniValue::VNUM)},
1438  {"scriptPubKey", UniValueType(UniValue::VSTR)},
1439  });
1440 
1441  uint256 txid = ParseHashO(prevOut, "txid");
1442 
1443  int nOut = find_value(prevOut, "vout").get_int();
1444  if (nOut < 0)
1445  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout must be positive");
1446 
1447  COutPoint out(txid, nOut);
1448  std::vector<unsigned char> pkData(ParseHexO(prevOut, "scriptPubKey"));
1449  CScript scriptPubKey(pkData.begin(), pkData.end());
1450 
1451  {
1452  const Coin& coin = view.AccessCoin(out);
1453  if (!coin.IsSpent() && coin.out.scriptPubKey != scriptPubKey) {
1454  std::string err("Previous output scriptPubKey mismatch:\n");
1455  err = err + ScriptToAsmStr(coin.out.scriptPubKey) + "\nvs:\n"+
1456  ScriptToAsmStr(scriptPubKey);
1458  }
1459  Coin newcoin;
1460  newcoin.out.scriptPubKey = scriptPubKey;
1461  newcoin.out.nValue = 0;
1462  if (prevOut.exists("amount")) {
1463  newcoin.out.nValue = AmountFromValue(find_value(prevOut, "amount"));
1464  }
1465  newcoin.nHeight = 1;
1466  view.AddCoin(out, std::move(newcoin), true);
1467  }
1468 
1469  // if redeemScript given and not using the local wallet (private keys
1470  // given), add redeemScript to the tempKeystore so it can be signed:
1471  if (fGivenKeys && (scriptPubKey.IsPayToScriptHash() || scriptPubKey.IsPayToWitnessScriptHash())) {
1472  RPCTypeCheckObj(prevOut,
1473  {
1474  {"txid", UniValueType(UniValue::VSTR)},
1475  {"vout", UniValueType(UniValue::VNUM)},
1476  {"scriptPubKey", UniValueType(UniValue::VSTR)},
1477  {"redeemScript", UniValueType(UniValue::VSTR)},
1478  });
1479  UniValue v = find_value(prevOut, "redeemScript");
1480  if (!v.isNull()) {
1481  std::vector<unsigned char> rsData(ParseHexV(v, "redeemScript"));
1482  CScript redeemScript(rsData.begin(), rsData.end());
1483  tempKeystore.AddCScript(redeemScript);
1484  }
1485  }
1486  }
1487  }
1488 
1489 #ifdef ENABLE_WALLET
1490  const CKeyStore& keystore = ((fGivenKeys || !pwallet) ? tempKeystore : *pwallet);
1491 #else
1492  const CKeyStore& keystore = tempKeystore;
1493 #endif
1494 
1495  int nHashType = SIGHASH_ALL;
1496  if (!request.params[3].isNull()) {
1497  static std::map<std::string, int> mapSigHashValues = {
1498  {std::string("ALL"), int(SIGHASH_ALL)},
1499  {std::string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY)},
1500  {std::string("NONE"), int(SIGHASH_NONE)},
1501  {std::string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY)},
1502  {std::string("SINGLE"), int(SIGHASH_SINGLE)},
1503  {std::string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)},
1504  };
1505  std::string strHashType = request.params[3].get_str();
1506  if (mapSigHashValues.count(strHashType))
1507  nHashType = mapSigHashValues[strHashType];
1508  else
1509  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param");
1510  }
1511 
1512  bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
1513 
1514  // Script verification errors
1515  UniValue vErrors(UniValue::VARR);
1516 
1517  // Use CTransaction for the constant parts of the
1518  // transaction to avoid rehashing.
1519  const CTransaction txConst(mtx);
1520  // Sign what we can:
1521  for (unsigned int i = 0; i < mtx.vin.size(); i++) {
1522  CTxIn& txin = mtx.vin[i];
1523  const Coin& coin = view.AccessCoin(txin.prevout);
1524  if (coin.IsSpent()) {
1525  TxInErrorToJSON(txin, vErrors, "Input not found or already spent");
1526  continue;
1527  }
1528  const CScript& prevPubKey = coin.out.scriptPubKey;
1529  const CAmount& amount = coin.out.nValue;
1530 
1531  SignatureData sigdata;
1532  // Only sign SIGHASH_SINGLE if there's a corresponding output:
1533  if (!fHashSingle || (i < mtx.vout.size()))
1534  ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mtx, i, amount, nHashType), prevPubKey, sigdata);
1535  sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(mtx, i));
1536 
1537  UpdateTransaction(mtx, i, sigdata);
1538 
1539  ScriptError serror = SCRIPT_ERR_OK;
1540  if (!VerifyScript(txin.scriptSig, prevPubKey, &txin.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount), &serror)) {
1541  if (serror == SCRIPT_ERR_INVALID_STACK_OPERATION) {
1542  // Unable to sign input and verification failed (possible attempt to partially sign).
1543  TxInErrorToJSON(txin, vErrors, "Unable to sign input, invalid stack size (possibly missing key)");
1544  } else {
1545  TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror));
1546  }
1547  }
1548  }
1549  bool fComplete = vErrors.empty();
1550 
1551  UniValue result(UniValue::VOBJ);
1552  result.push_back(Pair("hex", EncodeHexTx(mtx)));
1553  result.push_back(Pair("complete", fComplete));
1554  if (!vErrors.empty()) {
1555  result.push_back(Pair("errors", vErrors));
1556  }
1557 
1558  return result;
1559 }
1560 
1562 {
1563  if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
1564  throw std::runtime_error(
1565  "sendrawtransaction \"hexstring\" ( allowhighfees )\n"
1566  "\nSubmits raw transaction (serialized, hex-encoded) to local node and network.\n"
1567  "\nAlso see createrawtransaction and signrawtransaction calls.\n"
1568  "\nArguments:\n"
1569  "1. \"hexstring\" (string, required) The hex string of the raw transaction)\n"
1570  "2. allowhighfees (boolean, optional, default=false) Allow high fees\n"
1571  "\nResult:\n"
1572  "\"hex\" (string) The transaction hash in hex\n"
1573  "\nExamples:\n"
1574  "\nCreate a transaction\n"
1575  + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") +
1576  "Sign the transaction, and get back the hex\n"
1577  + HelpExampleCli("signrawtransaction", "\"myhex\"") +
1578  "\nSend the transaction (signed hex)\n"
1579  + HelpExampleCli("sendrawtransaction", "\"signedhex\"") +
1580  "\nAs a json rpc call\n"
1581  + HelpExampleRpc("sendrawtransaction", "\"signedhex\"")
1582  );
1583 
1584  ObserveSafeMode();
1585  LOCK(cs_main);
1586  RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL});
1587 
1588  // parse hex string from parameter
1589  CMutableTransaction mtx;
1590  if (!DecodeHexTx(mtx, request.params[0].get_str()))
1591  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
1592  CTransactionRef tx(MakeTransactionRef(std::move(mtx)));
1593  const uint256& hashTx = tx->GetHash();
1594 
1595  CAmount nMaxRawTxFee = maxTxFee;
1596  if (!request.params[1].isNull() && request.params[1].get_bool())
1597  nMaxRawTxFee = 0;
1598 
1599  CCoinsViewCache &view = *pcoinsTip;
1600  bool fHaveChain = false;
1601  for (size_t o = 0; !fHaveChain && o < tx->vout.size(); o++) {
1602  const Coin& existingCoin = view.AccessCoin(COutPoint(hashTx, o));
1603  fHaveChain = !existingCoin.IsSpent();
1604  }
1605  bool fHaveMempool = mempool.exists(hashTx);
1606  if (!fHaveMempool && !fHaveChain) {
1607  // push to local node and sync with wallets
1608  CValidationState state;
1609  bool fMissingInputs;
1610  if (!AcceptToMemoryPool(mempool, state, std::move(tx), &fMissingInputs,
1611  nullptr /* plTxnReplaced */, false /* bypass_limits */, nMaxRawTxFee)) {
1612  if (state.IsInvalid()) {
1613  throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
1614  } else {
1615  if (fMissingInputs) {
1616  throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs");
1617  }
1619  }
1620  }
1621  } else if (fHaveChain) {
1622  throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain");
1623  }
1624  if(!g_connman)
1625  throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
1626 
1627  CInv inv(MSG_TX, hashTx);
1628  g_connman->ForEachNode([&inv](CNode* pnode)
1629  {
1630  pnode->PushInventory(inv);
1631  });
1632  return hashTx.GetHex();
1633 }
1634 
1635 static const CRPCCommand commands[] =
1636 { // category name actor (function) argNames
1637  // --------------------- ------------------------ ----------------------- ----------
1638  { "rawtransactions", "getrawtransaction", &getrawtransaction, {"txid","verbose"} },
1639  { "rawtransactions", "createrawtransaction", &createrawtransaction, {"inputs","outputs","locktime"} },
1640  { "rawtransactions", "decoderawtransaction", &decoderawtransaction, {"hexstring"} },
1641  { "rawtransactions", "decodescript", &decodescript, {"hexstring"} },
1642  { "rawtransactions", "sendrawtransaction", &sendrawtransaction, {"hexstring","allowhighfees"} },
1643  { "rawtransactions", "combinerawtransaction", &combinerawtransaction, {"txs"} },
1644  { "rawtransactions", "signrawtransaction", &signrawtransaction, {"hexstring","prevtxs","privkeys","sighashtype"} }, /* uses wallet if enabled */
1645 
1646  { "blockchain", "gettxoutproof", &gettxoutproof, {"txids", "blockhash"} },
1647  { "blockchain", "verifytxoutproof", &verifytxoutproof, {"proof"} },
1648 };
1649 
1651 {
1652  for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
1653  t.appendCommand(commands[vcidx].name, &commands[vcidx]);
1654 }
CAmount nValue
Definition: transaction.h:140
const Coin & AccessByTxid(const CCoinsViewCache &view, const uint256 &txid)
Utility function to find any unspent output with a given txid.
Definition: coins.cpp:522
void RPCTypeCheckObj(const UniValue &o, const std::map< std::string, UniValueType > &typesExpected, bool fAllowNull, bool fStrict)
Definition: server.cpp:83
Aliases for backward compatibility.
Definition: protocol.h:64
uint256 ParseHashO(const UniValue &o, std::string strKey)
Definition: server.cpp:138
CTxMemPool mempool
std::vector< unsigned char > ParseHexO(const UniValue &o, std::string strKey)
Definition: server.cpp:151
bool IsSpent() const
Definition: coins.h:78
void UpdateTransaction(CMutableTransaction &tx, unsigned int nIn, const SignatureData &data)
Definition: sign.cpp:236
bool isObject() const
Definition: univalue.h:86
#define OWNER_ASSET_AMOUNT
Definition: assets.h:35
#define UNIQUE_ASSET_AMOUNT
Definition: assets.h:36
SignatureData DataFromTransaction(const CMutableTransaction &tx, unsigned int nIn)
Extract signature data from a transaction, and insert it.
Definition: sign.cpp:227
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:89
void AddCoin(const COutPoint &outpoint, Coin &&coin, bool potential_overwrite)
Add a coin.
Definition: coins.cpp:76
void ConstructOwnerTransaction(CScript &script) const
Definition: assets.cpp:510
bool isBool() const
Definition: univalue.h:82
void ConstructTransaction(CScript &script) const
Definition: assets.cpp:4435
UniValue combinerawtransaction(const JSONRPCRequest &request)
const std::vector< UniValue > & getValues() const
#define UNIQUE_ASSET_UNITS
Definition: assets.h:37
Raven RPC command dispatcher.
Definition: server.h:143
int64_t GetBlockTime() const
Definition: chain.h:299
std::string strName
Definition: assettypes.h:239
enum ScriptError_t ScriptError
int8_t units
Definition: assettypes.h:102
CScript scriptPubKey
Definition: transaction.h:141
int8_t nReissuable
Definition: assettypes.h:242
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or a pruned one if not found.
Definition: coins.cpp:390
bool get_bool() const
void SetBackend(CCoinsView &viewIn)
Definition: coins.cpp:37
bool ContextualCheckReissueAsset(CAssetsCache *assetCache, const CReissueAsset &reissue_asset, std::string &strError, const CTransaction &tx)
Definition: assets.cpp:5273
A UTXO entry.
Definition: coins.h:32
Definition: block.h:73
CCriticalSection cs_wallet
Definition: wallet.h:751
unsigned int inputIndex
Definition: spentindex.h:42
#define strprintf
Definition: tinyformat.h:1054
CAmount maxTxFee
Absolute maximum transaction fee (in satoshis) used by wallet and mempool (rejects high fee in sendra...
Definition: validation.cpp:105
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
inv message data
Definition: protocol.h:397
std::vector< CTxIn > vin
Definition: transaction.h:391
CScriptWitness scriptWitness
Definition: transaction.h:73
bool AssetFromScript(const CScript &scriptPubKey, CNewAsset &assetNew, std::string &strAddress)
Definition: assets.cpp:664
bool TransferAssetFromScript(const CScript &scriptPubKey, CAssetTransfer &assetTransfer, std::string &strAddress)
Get specific asset type metadata from the given scripts.
Definition: assets.cpp:638
int Height() const
Return the maximal height in the chain.
Definition: chain.h:479
CCriticalSection cs_main
Global state.
Definition: validation.cpp:72
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
Definition: standard.cpp:402
CTxOut out
unspent transaction output
Definition: coins.h:36
void ConstructTransaction(CScript &script) const
Definition: assets.cpp:1555
CTxDestination DecodeDestination(const std::string &str)
Definition: base58.cpp:333
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
bool AddCScript(const CScript &redeemScript) override
Support for BIP 0013 : see https://github.com/raven/bips/blob/master/bip-0013.mediawiki.
Definition: keystore.cpp:40
std::vector< std::vector< unsigned char > > stack
Definition: script.h:701
UniValue decoderawtransaction(const JSONRPCRequest &request)
const std::string & get_str() const
std::string strName
Definition: assettypes.h:100
void ConstructTransaction(CScript &script) const
Definition: assets.cpp:1581
bool isNum() const
Definition: univalue.h:84
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: server.cpp:527
const UniValue & get_array() const
const std::string CURRENCY_UNIT
Definition: feerate.cpp:11
bool isStr() const
Definition: univalue.h:83
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:147
int64_t get_int64() const
UniValue ValueFromAmount(const CAmount &amount, const int8_t units)
Definition: core_write.cpp:38
CKey GetKey()
Definition: base58.cpp:301
const std::vector< std::string > & getKeys() const
std::string strName
Definition: assettypes.h:190
bool ReissueAssetFromScript(const CScript &scriptPubKey, CReissueAsset &reissue, std::string &strAddress)
Definition: assets.cpp:789
bool IsValid(std::string &strError) const
Definition: assets.cpp:1503
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:436
bool appendCommand(const std::string &name, const CRPCCommand *pcmd)
Appends a CRPCCommand to the dispatch table.
Definition: server.cpp:299
std::string strIPFSHash
Definition: assettypes.h:105
bool ProduceSignature(const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
Definition: sign.cpp:179
#define ASSET_TRANSFER_STRING
Definition: assets.h:47
bool IsNull() const
Definition: uint256.h:33
bool IsCoinBase() const
Definition: transaction.h:360
std::string HelpRequiringPassphrase(CWallet *const pwallet)
Definition: rpcwallet.cpp:56
void PushInventory(const CInv &inv)
Definition: net.h:820
void RPCTypeCheck(const UniValue &params, const std::list< UniValue::VType > &typesExpected, bool fAllowNull)
Type-check arguments; throws JSONRPCError if wrong type given.
Definition: server.cpp:58
#define OWNER_UNITS
Definition: assets.h:34
const std::vector< CTxIn > vin
Definition: transaction.h:287
Invalid, missing or duplicate parameter.
Definition: protocol.h:54
uint256 ParseHashV(const UniValue &v, std::string strName)
Utilities: convert hex-encoded Values (throws error if not hex).
Definition: server.cpp:125
int8_t nReissuable
Definition: assettypes.h:103
const UniValue & find_value(const UniValue &obj, const std::string &name)
Definition: univalue.cpp:236
SignatureData CombineSignatures(const CScript &scriptPubKey, const BaseSignatureChecker &checker, const SignatureData &scriptSig1, const SignatureData &scriptSig2)
Combine two script signatures using a generic signature checker, intelligently, possibly with OP_0 pl...
Definition: sign.cpp:438
std::string ToString() const
Definition: base58.cpp:194
const char * ScriptErrorString(const ScriptError serror)
Definition: script_error.cpp:9
int64_t CAmount
Amount in corbies (Can be negative)
Definition: amount.h:13
General error during transaction or block submission.
Definition: protocol.h:57
uint32_t nHeight
at which height this containing transaction was included in the active block chain ...
Definition: coins.h:42
iterator end()
Definition: prevector.h:293
CCoinsViewCache * pcoinsTip
Global variable that points to the active CCoinsView (protected by cs_main)
Definition: validation.cpp:223
#define LOCK2(cs1, cs2)
Definition: sync.h:177
std::string name
Definition: server.h:135
bool IsAssetNameValid(const std::string &name, AssetType &assetType, std::string &error)
Definition: assets.cpp:207
#define UNIQUE_ASSETS_REISSUABLE
Definition: assets.h:38
int8_t nHasIPFS
Definition: assettypes.h:104
std::string DecodeAssetData(std::string encoded)
Decode and Encode IPFS hashes, or OIP hashes.
Definition: assets.cpp:3699
Used to relay blocks as header + vector<merkle branch> to filtered nodes.
Definition: merkleblock.h:128
bool IsValidDestinationString(const std::string &str, const CChainParams &params)
Definition: base58.cpp:338
bool push_back(const UniValue &val)
Definition: univalue.cpp:110
std::string ScriptToAsmStr(const CScript &script, const bool fAttemptSighashDecode=false)
Create the assembly string representation of a CScript object.
Definition: core_write.cpp:99
bool AreAssetsDeployed()
RVN START.
base58-encoded Raven addresses.
Definition: base58.h:103
bool AcceptToMemoryPool(CTxMemPool &pool, CValidationState &state, const CTransactionRef &tx, bool *pfMissingInputs, std::list< CTransactionRef > *plTxnReplaced, bool bypass_limits, const CAmount nAbsurdFee)
(try to) add transaction to memory pool plTxnReplaced will be appended to with all transactions repla...
bool IsInvalid() const
Definition: validation.h:72
UniValue transfer(const JSONRPCRequest &request)
Definition: assets.cpp:1101
Abstract view on the open txout dataset.
Definition: coins.h:152
UniValue params
Definition: server.h:45
CAssetsCache * GetCurrentAssetCache()
An input of a transaction.
Definition: transaction.h:67
bool DecodeHexTx(CMutableTransaction &tx, const std::string &strHexTx, bool fTryNoWitness=false)
Definition: core_read.cpp:112
#define LOCK(cs)
Definition: sync.h:176
void ConstructTransaction(CScript &script) const
Constructs a CScript that carries the asset name and quantity and adds to to the end of the given scr...
Definition: assets.cpp:495
#define ENABLE_WALLET
Definition: raven-config.h:39
bool ContextualCheckNewAsset(CAssetsCache *assetCache, const CNewAsset &asset, std::string &strError, bool fCheckMempool)
Definition: assets.cpp:5187
const uint256 & GetHash() const
Definition: transaction.h:320
bool exists(const std::string &key) const
Definition: univalue.h:77
#define OWNER_TAG
Definition: assets.h:32
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
Definition: chain.h:466
uint256 uint256S(const char *str)
Definition: uint256.h:150
bool SetString(const char *pszSecret)
Definition: base58.cpp:316
std::string GetRejectReason() const
Definition: validation.h:92
uint32_t n
Definition: transaction.h:26
UniValue decodescript(const JSONRPCRequest &request)
bool IsHex(const std::string &str)
const std::vector< CTxOut > vout
Definition: transaction.h:288
Unexpected type was passed as parameter.
Definition: protocol.h:51
bool empty() const
Definition: univalue.h:68
bool pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:135
bool exists(uint256 hash) const
Definition: txmempool.h:660
bool OwnerAssetFromScript(const CScript &scriptPubKey, std::string &assetName, std::string &strAddress)
Definition: assets.cpp:764
An output of a transaction.
Definition: transaction.h:137
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
Definition: validation.cpp:75
int get_int() const
std::string ToString() const
Definition: uint256.cpp:63
Invalid address or key.
Definition: protocol.h:52
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Raven scriptPubKey for the given CTxDestination.
Definition: standard.cpp:347
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: server.cpp:522
bool GetSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value)
CAmount AmountFromValue(const UniValue &value)
Definition: server.cpp:113
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:22
virtual bool AddKey(const CKey &key)
Definition: keystore.cpp:13
std::vector< CTxOut > vout
Definition: transaction.h:392
bool fTxIndex
Definition: validation.cpp:83
bool isNull() const
Definition: univalue.h:79
bool isTrue() const
Definition: univalue.h:80
void RegisterRawTransactionRPCCommands(CRPCTable &t)
Register raw transaction RPC commands.
CCriticalSection cs
Definition: txmempool.h:468
std::string GetUniqueAssetName(const std::string &parent, const std::string &tag)
Build a unique asset buy giving the root name, and the tag name (ROOT, TAG) => ROOT::TAG.
Definition: assets.cpp:399
std::string GetStrippedVerifierString(const std::string &verifier)
Definition: assets.cpp:4728
std::vector< unsigned char > ParseHexV(const UniValue &v, std::string strName)
Definition: server.cpp:142
AssetType
Definition: assettypes.h:21
CScript scriptSig
Definition: transaction.h:71
CAmount nAmount
Definition: assettypes.h:240
UniValue createrawtransaction(const JSONRPCRequest &request)
bool fHelp
Definition: server.h:46
RVN END.
Definition: validation.h:30
256-bit opaque blob.
Definition: uint256.h:123
CAmount nAmount
Definition: assettypes.h:101
void TxToJSON(const CTransaction &tx, const uint256 hashBlock, UniValue &entry, bool expanded=false)
std::vector< CTransactionRef > vtx
Definition: block.h:77
bool GetTransaction(const uint256 &hash, CTransactionRef &txOut, const Consensus::Params &consensusParams, uint256 &hashBlock, bool fAllowSlow)
Return transaction in txOut, and if it was found inside a block, its hash is placed in hashBlock...
const_iterator end() const
Definition: streams.h:236
#define ARRAYLEN(array)
std::string EncodeDestination(const CTxDestination &dest)
Definition: base58.cpp:326
const_iterator begin() const
Definition: streams.h:234
UniValue getrawtransaction(const JSONRPCRequest &request)
UniValue verifytxoutproof(const JSONRPCRequest &request)
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:172
const CChainParams & Params()
Return the currently selected parameters.
A base58-encoded secret key.
Definition: base58.h:123
UniValue sendrawtransaction(const JSONRPCRequest &request)
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:396
int RPCSerializationFlags()
Definition: server.cpp:559
uint32_t nSequence
Definition: transaction.h:72
const UniValue & get_obj() const
A virtual base class for key stores.
Definition: keystore.h:19
uint160 addressHash
Definition: spentindex.h:46
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:30
bool ContextualCheckVerifierString(CAssetsCache *cache, const std::string &verifier, const std::string &check_address, std::string &strError, bool fWithTags)
Definition: assets.cpp:4979
std::string GetHex() const
Definition: uint256.cpp:22
#define ASSET_REISSUE_STRING
Definition: assets.h:49
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances...
Definition: wallet.h:673
UniValue gettxoutproof(const JSONRPCRequest &request)
std::string EncodeHexTx(const CTransaction &tx, const int serializeFlags=0)
Definition: core_write.cpp:143
std::unique_ptr< CConnman > g_connman
Definition: init.cpp:81
CWallet * GetWalletForJSONRPCRequest(const JSONRPCRequest &request)
Figures out what wallet, if any, to use for a JSONRPCRequest.
Definition: rpcwallet.cpp:40
iterator begin()
Definition: prevector.h:291
unsigned int GetRejectCode() const
Definition: validation.h:91
void ScriptPubKeyToUniv(const CScript &scriptPubKey, UniValue &out, bool fIncludeHex)
Definition: core_write.cpp:150
void ObserveSafeMode()
Definition: safemode.cpp:7
A reference to a CScript: the Hash160 of its serialization (see script.h)
Definition: standard.h:23
A mutable version of CTransaction.
Definition: transaction.h:389
CAmount satoshis
Definition: spentindex.h:44
void TxToUniv(const CTransaction &tx, const uint256 &hashBlock, UniValue &entry, bool include_hex=true, int serialize_flags=0)
Definition: core_write.cpp:252
UniValue signrawtransaction(const JSONRPCRequest &request)
UniValue JSONRPCError(int code, const std::string &message)
Definition: protocol.cpp:55
No valid connection manager instance found.
Definition: protocol.h:75
size_t size() const
Definition: univalue.h:70
An encapsulated private key.
Definition: key.h:36
The basic transaction that is broadcasted on the network and contained in blocks. ...
Definition: transaction.h:270
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:185
#define ASSET_NEW_STRING
Definition: assets.h:48
Information about a peer.
Definition: net.h:596
bool ReadBlockFromDisk(CBlock &block, const CDiskBlockPos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:208
COutPoint prevout
Definition: transaction.h:70
std::string strIPFSHash
Definition: assettypes.h:243
CCoinsView that brings transactions from a memorypool into view.
Definition: txmempool.h:725
std::string EncodeAssetData(std::string decoded)
Definition: assets.cpp:3716
BlockMap mapBlockIndex
Definition: validation.cpp:74
bool isArray() const
Definition: univalue.h:85
Basic key store, that keeps keys in an address->secret map.
Definition: keystore.h:55
CAmount nAmount
Definition: assettypes.h:191
Wrapper for UniValue::VType, which includes typeAny: Used to denote don&#39;t care type.
Definition: server.h:33
UniValue reissue(const JSONRPCRequest &request)
Definition: assets.cpp:1465
Error parsing or validating structure in raw format.
Definition: protocol.h:56
bool IsValid() const
Check whether this private key is valid.
Definition: key.h:88
bool IsAssetNameAnRestricted(const std::string &name)
Check if an asset is a restricted asset.
Definition: assets.cpp:301
void EnsureWalletIsUnlocked(CWallet *const pwallet)
Definition: rpcwallet.cpp:80
uint256 hash
Definition: transaction.h:25