BSHA3  0.17.99
P2P Blockchain, based on Bitcoin
bsha3-tx.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2018 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #if defined(HAVE_CONFIG_H)
7 #endif
8 
9 #include <clientversion.h>
10 #include <coins.h>
11 #include <consensus/consensus.h>
12 #include <core_io.h>
13 #include <key_io.h>
14 #include <keystore.h>
15 #include <policy/policy.h>
16 #include <policy/rbf.h>
17 #include <primitives/transaction.h>
18 #include <script/script.h>
19 #include <script/sign.h>
20 #include <univalue.h>
21 #include <util.h>
22 #include <utilmoneystr.h>
23 #include <utilstrencodings.h>
24 
25 #include <memory>
26 #include <stdio.h>
27 
28 #include <boost/algorithm/string.hpp>
29 
30 static bool fCreateBlank;
31 static std::map<std::string,UniValue> registers;
32 static const int CONTINUE_EXECUTION=-1;
33 
34 const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr;
35 
36 static void SetupBitcoinTxArgs()
37 {
38  gArgs.AddArg("-?", "This help message", false, OptionsCategory::OPTIONS);
39  gArgs.AddArg("-create", "Create new, empty TX.", false, OptionsCategory::OPTIONS);
40  gArgs.AddArg("-json", "Select JSON output", false, OptionsCategory::OPTIONS);
41  gArgs.AddArg("-txid", "Output only the hex-encoded transaction id of the resultant transaction.", false, OptionsCategory::OPTIONS);
43 
44  gArgs.AddArg("delin=N", "Delete input N from TX", false, OptionsCategory::COMMANDS);
45  gArgs.AddArg("delout=N", "Delete output N from TX", false, OptionsCategory::COMMANDS);
46  gArgs.AddArg("in=TXID:VOUT(:SEQUENCE_NUMBER)", "Add input to TX", false, OptionsCategory::COMMANDS);
47  gArgs.AddArg("locktime=N", "Set TX lock time to N", false, OptionsCategory::COMMANDS);
48  gArgs.AddArg("nversion=N", "Set TX version to N", false, OptionsCategory::COMMANDS);
49  gArgs.AddArg("outaddr=VALUE:ADDRESS", "Add address-based output to TX", false, OptionsCategory::COMMANDS);
50  gArgs.AddArg("outdata=[VALUE:]DATA", "Add data-based output to TX", false, OptionsCategory::COMMANDS);
51  gArgs.AddArg("outmultisig=VALUE:REQUIRED:PUBKEYS:PUBKEY1:PUBKEY2:....[:FLAGS]", "Add Pay To n-of-m Multi-sig output to TX. n = REQUIRED, m = PUBKEYS. "
52  "Optionally add the \"W\" flag to produce a pay-to-witness-script-hash output. "
53  "Optionally add the \"S\" flag to wrap the output in a pay-to-script-hash.", false, OptionsCategory::COMMANDS);
54  gArgs.AddArg("outpubkey=VALUE:PUBKEY[:FLAGS]", "Add pay-to-pubkey output to TX. "
55  "Optionally add the \"W\" flag to produce a pay-to-witness-pubkey-hash output. "
56  "Optionally add the \"S\" flag to wrap the output in a pay-to-script-hash.", false, OptionsCategory::COMMANDS);
57  gArgs.AddArg("outscript=VALUE:SCRIPT[:FLAGS]", "Add raw script output to TX. "
58  "Optionally add the \"W\" flag to produce a pay-to-witness-script-hash output. "
59  "Optionally add the \"S\" flag to wrap the output in a pay-to-script-hash.", false, OptionsCategory::COMMANDS);
60  gArgs.AddArg("replaceable(=N)", "Set RBF opt-in sequence number for input N (if not provided, opt-in all available inputs)", false, OptionsCategory::COMMANDS);
61  gArgs.AddArg("sign=SIGHASH-FLAGS", "Add zero or more signatures to transaction. "
62  "This command requires JSON registers:"
63  "prevtxs=JSON object, "
64  "privatekeys=JSON object. "
65  "See signrawtransaction docs for format of sighash flags, JSON objects.", false, OptionsCategory::COMMANDS);
66 
67  gArgs.AddArg("load=NAME:FILENAME", "Load JSON file FILENAME into register NAME", false, OptionsCategory::REGISTER_COMMANDS);
68  gArgs.AddArg("set=NAME:JSON-STRING", "Set register NAME to given JSON-STRING", false, OptionsCategory::REGISTER_COMMANDS);
69 
70  // Hidden
71  gArgs.AddArg("-h", "", false, OptionsCategory::HIDDEN);
72  gArgs.AddArg("-help", "", false, OptionsCategory::HIDDEN);
73 }
74 
75 //
76 // This function returns either one of EXIT_ codes when it's expected to stop the process or
77 // CONTINUE_EXECUTION when it's expected to continue further.
78 //
79 static int AppInitRawTx(int argc, char* argv[])
80 {
81  //
82  // Parameters
83  //
84  SetupBitcoinTxArgs();
85  std::string error;
86  if (!gArgs.ParseParameters(argc, argv, error)) {
87  fprintf(stderr, "Error parsing command line arguments: %s\n", error.c_str());
88  return EXIT_FAILURE;
89  }
90 
91  // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
92  try {
94  } catch (const std::exception& e) {
95  fprintf(stderr, "Error: %s\n", e.what());
96  return EXIT_FAILURE;
97  }
98 
99  fCreateBlank = gArgs.GetBoolArg("-create", false);
100 
101  if (argc < 2 || HelpRequested(gArgs)) {
102  // First part of help message is specific to this utility
103  std::string strUsage = PACKAGE_NAME " bsha3-tx utility version " + FormatFullVersion() + "\n\n" +
104  "Usage: bsha3-tx [options] <hex-tx> [commands] Update hex-encoded bitcoin transaction\n" +
105  "or: bsha3-tx [options] -create [commands] Create hex-encoded bitcoin transaction\n" +
106  "\n";
107  strUsage += gArgs.GetHelpMessage();
108 
109  fprintf(stdout, "%s", strUsage.c_str());
110 
111  if (argc < 2) {
112  fprintf(stderr, "Error: too few parameters\n");
113  return EXIT_FAILURE;
114  }
115  return EXIT_SUCCESS;
116  }
117  return CONTINUE_EXECUTION;
118 }
119 
120 static void RegisterSetJson(const std::string& key, const std::string& rawJson)
121 {
122  UniValue val;
123  if (!val.read(rawJson)) {
124  std::string strErr = "Cannot parse JSON for key " + key;
125  throw std::runtime_error(strErr);
126  }
127 
128  registers[key] = val;
129 }
130 
131 static void RegisterSet(const std::string& strInput)
132 {
133  // separate NAME:VALUE in string
134  size_t pos = strInput.find(':');
135  if ((pos == std::string::npos) ||
136  (pos == 0) ||
137  (pos == (strInput.size() - 1)))
138  throw std::runtime_error("Register input requires NAME:VALUE");
139 
140  std::string key = strInput.substr(0, pos);
141  std::string valStr = strInput.substr(pos + 1, std::string::npos);
142 
143  RegisterSetJson(key, valStr);
144 }
145 
146 static void RegisterLoad(const std::string& strInput)
147 {
148  // separate NAME:FILENAME in string
149  size_t pos = strInput.find(':');
150  if ((pos == std::string::npos) ||
151  (pos == 0) ||
152  (pos == (strInput.size() - 1)))
153  throw std::runtime_error("Register load requires NAME:FILENAME");
154 
155  std::string key = strInput.substr(0, pos);
156  std::string filename = strInput.substr(pos + 1, std::string::npos);
157 
158  FILE *f = fopen(filename.c_str(), "r");
159  if (!f) {
160  std::string strErr = "Cannot open file " + filename;
161  throw std::runtime_error(strErr);
162  }
163 
164  // load file chunks into one big buffer
165  std::string valStr;
166  while ((!feof(f)) && (!ferror(f))) {
167  char buf[4096];
168  int bread = fread(buf, 1, sizeof(buf), f);
169  if (bread <= 0)
170  break;
171 
172  valStr.insert(valStr.size(), buf, bread);
173  }
174 
175  int error = ferror(f);
176  fclose(f);
177 
178  if (error) {
179  std::string strErr = "Error reading file " + filename;
180  throw std::runtime_error(strErr);
181  }
182 
183  // evaluate as JSON buffer register
184  RegisterSetJson(key, valStr);
185 }
186 
187 static CAmount ExtractAndValidateValue(const std::string& strValue)
188 {
189  CAmount value;
190  if (!ParseMoney(strValue, value))
191  throw std::runtime_error("invalid TX output value");
192  return value;
193 }
194 
195 static void MutateTxVersion(CMutableTransaction& tx, const std::string& cmdVal)
196 {
197  int64_t newVersion;
198  if (!ParseInt64(cmdVal, &newVersion) || newVersion < 1 || newVersion > CTransaction::MAX_STANDARD_VERSION)
199  throw std::runtime_error("Invalid TX version requested: '" + cmdVal + "'");
200 
201  tx.nVersion = (int) newVersion;
202 }
203 
204 static void MutateTxLocktime(CMutableTransaction& tx, const std::string& cmdVal)
205 {
206  int64_t newLocktime;
207  if (!ParseInt64(cmdVal, &newLocktime) || newLocktime < 0LL || newLocktime > 0xffffffffLL)
208  throw std::runtime_error("Invalid TX locktime requested: '" + cmdVal + "'");
209 
210  tx.nLockTime = (unsigned int) newLocktime;
211 }
212 
213 static void MutateTxRBFOptIn(CMutableTransaction& tx, const std::string& strInIdx)
214 {
215  // parse requested index
216  int64_t inIdx;
217  if (!ParseInt64(strInIdx, &inIdx) || inIdx < 0 || inIdx >= static_cast<int64_t>(tx.vin.size())) {
218  throw std::runtime_error("Invalid TX input index '" + strInIdx + "'");
219  }
220 
221  // set the nSequence to MAX_INT - 2 (= RBF opt in flag)
222  int cnt = 0;
223  for (CTxIn& txin : tx.vin) {
224  if (strInIdx == "" || cnt == inIdx) {
225  if (txin.nSequence > MAX_BIP125_RBF_SEQUENCE) {
226  txin.nSequence = MAX_BIP125_RBF_SEQUENCE;
227  }
228  }
229  ++cnt;
230  }
231 }
232 
233 static void MutateTxAddInput(CMutableTransaction& tx, const std::string& strInput)
234 {
235  std::vector<std::string> vStrInputParts;
236  boost::split(vStrInputParts, strInput, boost::is_any_of(":"));
237 
238  // separate TXID:VOUT in string
239  if (vStrInputParts.size()<2)
240  throw std::runtime_error("TX input missing separator");
241 
242  // extract and validate TXID
243  uint256 txid;
244  if (!ParseHashStr(vStrInputParts[0], txid)) {
245  throw std::runtime_error("invalid TX input txid");
246  }
247 
248  static const unsigned int minTxOutSz = 9;
249  static const unsigned int maxVout = MAX_BLOCK_WEIGHT / (WITNESS_SCALE_FACTOR * minTxOutSz);
250 
251  // extract and validate vout
252  const std::string& strVout = vStrInputParts[1];
253  int64_t vout;
254  if (!ParseInt64(strVout, &vout) || vout < 0 || vout > static_cast<int64_t>(maxVout))
255  throw std::runtime_error("invalid TX input vout '" + strVout + "'");
256 
257  // extract the optional sequence number
258  uint32_t nSequenceIn=std::numeric_limits<unsigned int>::max();
259  if (vStrInputParts.size() > 2)
260  nSequenceIn = std::stoul(vStrInputParts[2]);
261 
262  // append to transaction input list
263  CTxIn txin(txid, vout, CScript(), nSequenceIn);
264  tx.vin.push_back(txin);
265 }
266 
267 static void MutateTxAddOutAddr(CMutableTransaction& tx, const std::string& strInput)
268 {
269  // Separate into VALUE:ADDRESS
270  std::vector<std::string> vStrInputParts;
271  boost::split(vStrInputParts, strInput, boost::is_any_of(":"));
272 
273  if (vStrInputParts.size() != 2)
274  throw std::runtime_error("TX output missing or too many separators");
275 
276  // Extract and validate VALUE
277  CAmount value = ExtractAndValidateValue(vStrInputParts[0]);
278 
279  // extract and validate ADDRESS
280  std::string strAddr = vStrInputParts[1];
281  CTxDestination destination = DecodeDestination(strAddr);
282  if (!IsValidDestination(destination)) {
283  throw std::runtime_error("invalid TX output address");
284  }
285  CScript scriptPubKey = GetScriptForDestination(destination);
286 
287  // construct TxOut, append to transaction output list
288  CTxOut txout(value, scriptPubKey);
289  tx.vout.push_back(txout);
290 }
291 
292 static void MutateTxAddOutPubKey(CMutableTransaction& tx, const std::string& strInput)
293 {
294  // Separate into VALUE:PUBKEY[:FLAGS]
295  std::vector<std::string> vStrInputParts;
296  boost::split(vStrInputParts, strInput, boost::is_any_of(":"));
297 
298  if (vStrInputParts.size() < 2 || vStrInputParts.size() > 3)
299  throw std::runtime_error("TX output missing or too many separators");
300 
301  // Extract and validate VALUE
302  CAmount value = ExtractAndValidateValue(vStrInputParts[0]);
303 
304  // Extract and validate PUBKEY
305  CPubKey pubkey(ParseHex(vStrInputParts[1]));
306  if (!pubkey.IsFullyValid())
307  throw std::runtime_error("invalid TX output pubkey");
308  CScript scriptPubKey = GetScriptForRawPubKey(pubkey);
309 
310  // Extract and validate FLAGS
311  bool bSegWit = false;
312  bool bScriptHash = false;
313  if (vStrInputParts.size() == 3) {
314  std::string flags = vStrInputParts[2];
315  bSegWit = (flags.find('W') != std::string::npos);
316  bScriptHash = (flags.find('S') != std::string::npos);
317  }
318 
319  if (bSegWit) {
320  if (!pubkey.IsCompressed()) {
321  throw std::runtime_error("Uncompressed pubkeys are not useable for SegWit outputs");
322  }
323  // Call GetScriptForWitness() to build a P2WSH scriptPubKey
324  scriptPubKey = GetScriptForWitness(scriptPubKey);
325  }
326  if (bScriptHash) {
327  // Get the ID for the script, and then construct a P2SH destination for it.
328  scriptPubKey = GetScriptForDestination(CScriptID(scriptPubKey));
329  }
330 
331  // construct TxOut, append to transaction output list
332  CTxOut txout(value, scriptPubKey);
333  tx.vout.push_back(txout);
334 }
335 
336 static void MutateTxAddOutMultiSig(CMutableTransaction& tx, const std::string& strInput)
337 {
338  // Separate into VALUE:REQUIRED:NUMKEYS:PUBKEY1:PUBKEY2:....[:FLAGS]
339  std::vector<std::string> vStrInputParts;
340  boost::split(vStrInputParts, strInput, boost::is_any_of(":"));
341 
342  // Check that there are enough parameters
343  if (vStrInputParts.size()<3)
344  throw std::runtime_error("Not enough multisig parameters");
345 
346  // Extract and validate VALUE
347  CAmount value = ExtractAndValidateValue(vStrInputParts[0]);
348 
349  // Extract REQUIRED
350  uint32_t required = stoul(vStrInputParts[1]);
351 
352  // Extract NUMKEYS
353  uint32_t numkeys = stoul(vStrInputParts[2]);
354 
355  // Validate there are the correct number of pubkeys
356  if (vStrInputParts.size() < numkeys + 3)
357  throw std::runtime_error("incorrect number of multisig pubkeys");
358 
359  if (required < 1 || required > MAX_PUBKEYS_PER_MULTISIG || numkeys < 1 || numkeys > MAX_PUBKEYS_PER_MULTISIG || numkeys < required)
360  throw std::runtime_error("multisig parameter mismatch. Required " \
361  + std::to_string(required) + " of " + std::to_string(numkeys) + "signatures.");
362 
363  // extract and validate PUBKEYs
364  std::vector<CPubKey> pubkeys;
365  for(int pos = 1; pos <= int(numkeys); pos++) {
366  CPubKey pubkey(ParseHex(vStrInputParts[pos + 2]));
367  if (!pubkey.IsFullyValid())
368  throw std::runtime_error("invalid TX output pubkey");
369  pubkeys.push_back(pubkey);
370  }
371 
372  // Extract FLAGS
373  bool bSegWit = false;
374  bool bScriptHash = false;
375  if (vStrInputParts.size() == numkeys + 4) {
376  std::string flags = vStrInputParts.back();
377  bSegWit = (flags.find('W') != std::string::npos);
378  bScriptHash = (flags.find('S') != std::string::npos);
379  }
380  else if (vStrInputParts.size() > numkeys + 4) {
381  // Validate that there were no more parameters passed
382  throw std::runtime_error("Too many parameters");
383  }
384 
385  CScript scriptPubKey = GetScriptForMultisig(required, pubkeys);
386 
387  if (bSegWit) {
388  for (const CPubKey& pubkey : pubkeys) {
389  if (!pubkey.IsCompressed()) {
390  throw std::runtime_error("Uncompressed pubkeys are not useable for SegWit outputs");
391  }
392  }
393  // Call GetScriptForWitness() to build a P2WSH scriptPubKey
394  scriptPubKey = GetScriptForWitness(scriptPubKey);
395  }
396  if (bScriptHash) {
397  if (scriptPubKey.size() > MAX_SCRIPT_ELEMENT_SIZE) {
398  throw std::runtime_error(strprintf(
399  "redeemScript exceeds size limit: %d > %d", scriptPubKey.size(), MAX_SCRIPT_ELEMENT_SIZE));
400  }
401  // Get the ID for the script, and then construct a P2SH destination for it.
402  scriptPubKey = GetScriptForDestination(CScriptID(scriptPubKey));
403  }
404 
405  // construct TxOut, append to transaction output list
406  CTxOut txout(value, scriptPubKey);
407  tx.vout.push_back(txout);
408 }
409 
410 static void MutateTxAddOutData(CMutableTransaction& tx, const std::string& strInput)
411 {
412  CAmount value = 0;
413 
414  // separate [VALUE:]DATA in string
415  size_t pos = strInput.find(':');
416 
417  if (pos==0)
418  throw std::runtime_error("TX output value not specified");
419 
420  if (pos != std::string::npos) {
421  // Extract and validate VALUE
422  value = ExtractAndValidateValue(strInput.substr(0, pos));
423  }
424 
425  // extract and validate DATA
426  std::string strData = strInput.substr(pos + 1, std::string::npos);
427 
428  if (!IsHex(strData))
429  throw std::runtime_error("invalid TX output data");
430 
431  std::vector<unsigned char> data = ParseHex(strData);
432 
433  CTxOut txout(value, CScript() << OP_RETURN << data);
434  tx.vout.push_back(txout);
435 }
436 
437 static void MutateTxAddOutScript(CMutableTransaction& tx, const std::string& strInput)
438 {
439  // separate VALUE:SCRIPT[:FLAGS]
440  std::vector<std::string> vStrInputParts;
441  boost::split(vStrInputParts, strInput, boost::is_any_of(":"));
442  if (vStrInputParts.size() < 2)
443  throw std::runtime_error("TX output missing separator");
444 
445  // Extract and validate VALUE
446  CAmount value = ExtractAndValidateValue(vStrInputParts[0]);
447 
448  // extract and validate script
449  std::string strScript = vStrInputParts[1];
450  CScript scriptPubKey = ParseScript(strScript);
451 
452  // Extract FLAGS
453  bool bSegWit = false;
454  bool bScriptHash = false;
455  if (vStrInputParts.size() == 3) {
456  std::string flags = vStrInputParts.back();
457  bSegWit = (flags.find('W') != std::string::npos);
458  bScriptHash = (flags.find('S') != std::string::npos);
459  }
460 
461  if (scriptPubKey.size() > MAX_SCRIPT_SIZE) {
462  throw std::runtime_error(strprintf(
463  "script exceeds size limit: %d > %d", scriptPubKey.size(), MAX_SCRIPT_SIZE));
464  }
465 
466  if (bSegWit) {
467  scriptPubKey = GetScriptForWitness(scriptPubKey);
468  }
469  if (bScriptHash) {
470  if (scriptPubKey.size() > MAX_SCRIPT_ELEMENT_SIZE) {
471  throw std::runtime_error(strprintf(
472  "redeemScript exceeds size limit: %d > %d", scriptPubKey.size(), MAX_SCRIPT_ELEMENT_SIZE));
473  }
474  scriptPubKey = GetScriptForDestination(CScriptID(scriptPubKey));
475  }
476 
477  // construct TxOut, append to transaction output list
478  CTxOut txout(value, scriptPubKey);
479  tx.vout.push_back(txout);
480 }
481 
482 static void MutateTxDelInput(CMutableTransaction& tx, const std::string& strInIdx)
483 {
484  // parse requested deletion index
485  int64_t inIdx;
486  if (!ParseInt64(strInIdx, &inIdx) || inIdx < 0 || inIdx >= static_cast<int64_t>(tx.vin.size())) {
487  throw std::runtime_error("Invalid TX input index '" + strInIdx + "'");
488  }
489 
490  // delete input from transaction
491  tx.vin.erase(tx.vin.begin() + inIdx);
492 }
493 
494 static void MutateTxDelOutput(CMutableTransaction& tx, const std::string& strOutIdx)
495 {
496  // parse requested deletion index
497  int64_t outIdx;
498  if (!ParseInt64(strOutIdx, &outIdx) || outIdx < 0 || outIdx >= static_cast<int64_t>(tx.vout.size())) {
499  throw std::runtime_error("Invalid TX output index '" + strOutIdx + "'");
500  }
501 
502  // delete output from transaction
503  tx.vout.erase(tx.vout.begin() + outIdx);
504 }
505 
506 static const unsigned int N_SIGHASH_OPTS = 6;
507 static const struct {
508  const char *flagStr;
509  int flags;
510 } sighashOptions[N_SIGHASH_OPTS] = {
511  {"ALL", SIGHASH_ALL},
512  {"NONE", SIGHASH_NONE},
513  {"SINGLE", SIGHASH_SINGLE},
514  {"ALL|ANYONECANPAY", SIGHASH_ALL|SIGHASH_ANYONECANPAY},
515  {"NONE|ANYONECANPAY", SIGHASH_NONE|SIGHASH_ANYONECANPAY},
516  {"SINGLE|ANYONECANPAY", SIGHASH_SINGLE|SIGHASH_ANYONECANPAY},
517 };
518 
519 static bool findSighashFlags(int& flags, const std::string& flagStr)
520 {
521  flags = 0;
522 
523  for (unsigned int i = 0; i < N_SIGHASH_OPTS; i++) {
524  if (flagStr == sighashOptions[i].flagStr) {
525  flags = sighashOptions[i].flags;
526  return true;
527  }
528  }
529 
530  return false;
531 }
532 
533 static CAmount AmountFromValue(const UniValue& value)
534 {
535  if (!value.isNum() && !value.isStr())
536  throw std::runtime_error("Amount is not a number or string");
537  CAmount amount;
538  if (!ParseFixedPoint(value.getValStr(), 8, &amount))
539  throw std::runtime_error("Invalid amount");
540  if (!MoneyRange(amount))
541  throw std::runtime_error("Amount out of range");
542  return amount;
543 }
544 
545 static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
546 {
547  int nHashType = SIGHASH_ALL;
548 
549  if (flagStr.size() > 0)
550  if (!findSighashFlags(nHashType, flagStr))
551  throw std::runtime_error("unknown sighash flag/sign option");
552 
553  // mergedTx will end up with all the signatures; it
554  // starts as a clone of the raw tx:
555  CMutableTransaction mergedTx{tx};
556  const CMutableTransaction txv{tx};
557  CCoinsView viewDummy;
558  CCoinsViewCache view(&viewDummy);
559 
560  if (!registers.count("privatekeys"))
561  throw std::runtime_error("privatekeys register variable must be set.");
562  CBasicKeyStore tempKeystore;
563  UniValue keysObj = registers["privatekeys"];
564 
565  for (unsigned int kidx = 0; kidx < keysObj.size(); kidx++) {
566  if (!keysObj[kidx].isStr())
567  throw std::runtime_error("privatekey not a std::string");
568  CKey key = DecodeSecret(keysObj[kidx].getValStr());
569  if (!key.IsValid()) {
570  throw std::runtime_error("privatekey not valid");
571  }
572  tempKeystore.AddKey(key);
573  }
574 
575  // Add previous txouts given in the RPC call:
576  if (!registers.count("prevtxs"))
577  throw std::runtime_error("prevtxs register variable must be set.");
578  UniValue prevtxsObj = registers["prevtxs"];
579  {
580  for (unsigned int previdx = 0; previdx < prevtxsObj.size(); previdx++) {
581  UniValue prevOut = prevtxsObj[previdx];
582  if (!prevOut.isObject())
583  throw std::runtime_error("expected prevtxs internal object");
584 
585  std::map<std::string, UniValue::VType> types = {
586  {"txid", UniValue::VSTR},
587  {"vout", UniValue::VNUM},
588  {"scriptPubKey", UniValue::VSTR},
589  };
590  if (!prevOut.checkObject(types))
591  throw std::runtime_error("prevtxs internal object typecheck fail");
592 
593  uint256 txid;
594  if (!ParseHashStr(prevOut["txid"].get_str(), txid)) {
595  throw std::runtime_error("txid must be hexadecimal string (not '" + prevOut["txid"].get_str() + "')");
596  }
597 
598  const int nOut = prevOut["vout"].get_int();
599  if (nOut < 0)
600  throw std::runtime_error("vout must be positive");
601 
602  COutPoint out(txid, nOut);
603  std::vector<unsigned char> pkData(ParseHexUV(prevOut["scriptPubKey"], "scriptPubKey"));
604  CScript scriptPubKey(pkData.begin(), pkData.end());
605 
606  {
607  const Coin& coin = view.AccessCoin(out);
608  if (!coin.IsSpent() && coin.out.scriptPubKey != scriptPubKey) {
609  std::string err("Previous output scriptPubKey mismatch:\n");
610  err = err + ScriptToAsmStr(coin.out.scriptPubKey) + "\nvs:\n"+
611  ScriptToAsmStr(scriptPubKey);
612  throw std::runtime_error(err);
613  }
614  Coin newcoin;
615  newcoin.out.scriptPubKey = scriptPubKey;
616  newcoin.out.nValue = 0;
617  if (prevOut.exists("amount")) {
618  newcoin.out.nValue = AmountFromValue(prevOut["amount"]);
619  }
620  newcoin.nHeight = 1;
621  view.AddCoin(out, std::move(newcoin), true);
622  }
623 
624  // if redeemScript given and private keys given,
625  // add redeemScript to the tempKeystore so it can be signed:
626  if ((scriptPubKey.IsPayToScriptHash() || scriptPubKey.IsPayToWitnessScriptHash()) &&
627  prevOut.exists("redeemScript")) {
628  UniValue v = prevOut["redeemScript"];
629  std::vector<unsigned char> rsData(ParseHexUV(v, "redeemScript"));
630  CScript redeemScript(rsData.begin(), rsData.end());
631  tempKeystore.AddCScript(redeemScript);
632  }
633  }
634  }
635 
636  const CKeyStore& keystore = tempKeystore;
637 
638  bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
639 
640  // Sign what we can:
641  for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
642  CTxIn& txin = mergedTx.vin[i];
643  const Coin& coin = view.AccessCoin(txin.prevout);
644  if (coin.IsSpent()) {
645  continue;
646  }
647  const CScript& prevPubKey = coin.out.scriptPubKey;
648  const CAmount& amount = coin.out.nValue;
649 
650  SignatureData sigdata = DataFromTransaction(mergedTx, i, coin.out);
651  // Only sign SIGHASH_SINGLE if there's a corresponding output:
652  if (!fHashSingle || (i < mergedTx.vout.size()))
653  ProduceSignature(keystore, MutableTransactionSignatureCreator(&mergedTx, i, amount, nHashType), prevPubKey, sigdata);
654 
655  UpdateInput(txin, sigdata);
656  }
657 
658  tx = mergedTx;
659 }
660 
662 {
664 
665 public:
667  ECC_Start();
668  }
670  ECC_Stop();
671  }
672 };
673 
674 static void MutateTx(CMutableTransaction& tx, const std::string& command,
675  const std::string& commandVal)
676 {
677  std::unique_ptr<Secp256k1Init> ecc;
678 
679  if (command == "nversion")
680  MutateTxVersion(tx, commandVal);
681  else if (command == "locktime")
682  MutateTxLocktime(tx, commandVal);
683  else if (command == "replaceable") {
684  MutateTxRBFOptIn(tx, commandVal);
685  }
686 
687  else if (command == "delin")
688  MutateTxDelInput(tx, commandVal);
689  else if (command == "in")
690  MutateTxAddInput(tx, commandVal);
691 
692  else if (command == "delout")
693  MutateTxDelOutput(tx, commandVal);
694  else if (command == "outaddr")
695  MutateTxAddOutAddr(tx, commandVal);
696  else if (command == "outpubkey") {
697  ecc.reset(new Secp256k1Init());
698  MutateTxAddOutPubKey(tx, commandVal);
699  } else if (command == "outmultisig") {
700  ecc.reset(new Secp256k1Init());
701  MutateTxAddOutMultiSig(tx, commandVal);
702  } else if (command == "outscript")
703  MutateTxAddOutScript(tx, commandVal);
704  else if (command == "outdata")
705  MutateTxAddOutData(tx, commandVal);
706 
707  else if (command == "sign") {
708  ecc.reset(new Secp256k1Init());
709  MutateTxSign(tx, commandVal);
710  }
711 
712  else if (command == "load")
713  RegisterLoad(commandVal);
714 
715  else if (command == "set")
716  RegisterSet(commandVal);
717 
718  else
719  throw std::runtime_error("unknown command");
720 }
721 
722 static void OutputTxJSON(const CTransaction& tx)
723 {
724  UniValue entry(UniValue::VOBJ);
725  TxToUniv(tx, uint256(), entry);
726 
727  std::string jsonOutput = entry.write(4);
728  fprintf(stdout, "%s\n", jsonOutput.c_str());
729 }
730 
731 static void OutputTxHash(const CTransaction& tx)
732 {
733  std::string strHexHash = tx.GetHash().GetHex(); // the hex-encoded transaction hash (aka the transaction id)
734 
735  fprintf(stdout, "%s\n", strHexHash.c_str());
736 }
737 
738 static void OutputTxHex(const CTransaction& tx)
739 {
740  std::string strHex = EncodeHexTx(tx);
741 
742  fprintf(stdout, "%s\n", strHex.c_str());
743 }
744 
745 static void OutputTx(const CTransaction& tx)
746 {
747  if (gArgs.GetBoolArg("-json", false))
748  OutputTxJSON(tx);
749  else if (gArgs.GetBoolArg("-txid", false))
750  OutputTxHash(tx);
751  else
752  OutputTxHex(tx);
753 }
754 
755 static std::string readStdin()
756 {
757  char buf[4096];
758  std::string ret;
759 
760  while (!feof(stdin)) {
761  size_t bread = fread(buf, 1, sizeof(buf), stdin);
762  ret.append(buf, bread);
763  if (bread < sizeof(buf))
764  break;
765  }
766 
767  if (ferror(stdin))
768  throw std::runtime_error("error reading stdin");
769 
770  boost::algorithm::trim_right(ret);
771 
772  return ret;
773 }
774 
775 static int CommandLineRawTx(int argc, char* argv[])
776 {
777  std::string strPrint;
778  int nRet = 0;
779  try {
780  // Skip switches; Permit common stdin convention "-"
781  while (argc > 1 && IsSwitchChar(argv[1][0]) &&
782  (argv[1][1] != 0)) {
783  argc--;
784  argv++;
785  }
786 
788  int startArg;
789 
790  if (!fCreateBlank) {
791  // require at least one param
792  if (argc < 2)
793  throw std::runtime_error("too few parameters");
794 
795  // param: hex-encoded bitcoin transaction
796  std::string strHexTx(argv[1]);
797  if (strHexTx == "-") // "-" implies standard input
798  strHexTx = readStdin();
799 
800  if (!DecodeHexTx(tx, strHexTx, true))
801  throw std::runtime_error("invalid transaction encoding");
802 
803  startArg = 2;
804  } else
805  startArg = 1;
806 
807  for (int i = startArg; i < argc; i++) {
808  std::string arg = argv[i];
809  std::string key, value;
810  size_t eqpos = arg.find('=');
811  if (eqpos == std::string::npos)
812  key = arg;
813  else {
814  key = arg.substr(0, eqpos);
815  value = arg.substr(eqpos + 1);
816  }
817 
818  MutateTx(tx, key, value);
819  }
820 
821  OutputTx(tx);
822  }
823 
824  catch (const boost::thread_interrupted&) {
825  throw;
826  }
827  catch (const std::exception& e) {
828  strPrint = std::string("error: ") + e.what();
829  nRet = EXIT_FAILURE;
830  }
831  catch (...) {
832  PrintExceptionContinue(nullptr, "CommandLineRawTx()");
833  throw;
834  }
835 
836  if (strPrint != "") {
837  fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str());
838  }
839  return nRet;
840 }
841 
842 int main(int argc, char* argv[])
843 {
845 
846  try {
847  int ret = AppInitRawTx(argc, argv);
848  if (ret != CONTINUE_EXECUTION)
849  return ret;
850  }
851  catch (const std::exception& e) {
852  PrintExceptionContinue(&e, "AppInitRawTx()");
853  return EXIT_FAILURE;
854  } catch (...) {
855  PrintExceptionContinue(nullptr, "AppInitRawTx()");
856  return EXIT_FAILURE;
857  }
858 
859  int ret = EXIT_FAILURE;
860  try {
861  ret = CommandLineRawTx(argc, argv);
862  }
863  catch (const std::exception& e) {
864  PrintExceptionContinue(&e, "CommandLineRawTx()");
865  } catch (...) {
866  PrintExceptionContinue(nullptr, "CommandLineRawTx()");
867  }
868  return ret;
869 }
std::vector< unsigned char > ParseHexUV(const UniValue &v, const std::string &strName)
Definition: core_read.cpp:205
CAmount nValue
Definition: transaction.h:134
bool HelpRequested(const ArgsManager &args)
Definition: util.cpp:662
bool IsSpent() const
Definition: coins.h:75
bool isObject() const
Definition: univalue.h:85
void ECC_Start()
Initialize the elliptic curve support.
Definition: key.cpp:343
static const int32_t MAX_STANDARD_VERSION
Definition: transaction.h:274
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:13
CScript scriptPubKey
Definition: transaction.h:135
A UTXO entry.
Definition: coins.h:29
bool read(const char *raw, size_t len)
#define strprintf
Definition: tinyformat.h:1066
bool IsPayToScriptHash() const
Definition: script.cpp:197
std::vector< CTxIn > vin
Definition: transaction.h:362
UniValue ret(UniValue::VARR)
Definition: rpcwallet.cpp:1140
bool MoneyRange(const CAmount &nValue)
Definition: amount.h:26
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
Definition: standard.cpp:324
CTxOut out
unspent transaction output
Definition: coins.h:33
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
Definition: standard.cpp:296
bool AddCScript(const CScript &redeemScript) override
Support for BIP 0013 : see https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki.
Definition: keystore.cpp:86
#define PACKAGE_NAME
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
Definition: util.cpp:698
bool isNum() const
Definition: univalue.h:83
bool ParseParameters(int argc, const char *const argv[], std::string &error)
Definition: util.cpp:411
bool isStr() const
Definition: univalue.h:82
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: util.cpp:542
A signature creator for transactions.
Definition: sign.h:83
const std::string & getValStr() const
Definition: univalue.h:66
const std::function< std::string(const char *)> G_TRANSLATION_FUN
Translate a message to the native language of the user.
Definition: bsha3-tx.cpp:34
std::string GetHelpMessage() const
Get the help string.
Definition: util.cpp:593
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
uint32_t nHeight
at which height this containing transaction was included in the active block chain ...
Definition: coins.h:39
bool ParseInt64(const std::string &str, int64_t *out)
Convert string to signed 64-bit integer with strict parse error feedback.
Users of this module must hold an ECCVerifyHandle.
Definition: pubkey.h:254
std::string ScriptToAsmStr(const CScript &script, const bool fAttemptSighashDecode=false)
Create the assembly string representation of a CScript object.
Definition: core_write.cpp:87
Abstract view on the open txout dataset.
Definition: coins.h:145
An input of a transaction.
Definition: transaction.h:61
boost::variant< CNoDestination, CKeyID, CScriptID, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:123
void ECC_Stop()
Deinitialize the elliptic curve support.
Definition: key.cpp:360
const uint256 & GetHash() const
Definition: transaction.h:316
bool exists(const std::string &key) const
Definition: univalue.h:76
void SelectParams(const std::string &network)
Sets the params returned by Params() to those for the given BIP70 chain name.
bool AddKey(const CKey &key)
Definition: keystore.h:61
bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out)
Parse number as fixed point according to JSON number syntax.
An encapsulated public key.
Definition: pubkey.h:30
bool IsHex(const std::string &str)
int main(int argc, char *argv[])
Definition: bsha3-tx.cpp:842
bool ParseMoney(const std::string &str, CAmount &nRet)
An output of a transaction.
Definition: transaction.h:131
int get_int() const
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
Definition: standard.cpp:288
const char * flagStr
Definition: bsha3-tx.cpp:508
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:18
std::vector< CTxOut > vout
Definition: transaction.h:363
std::string FormatFullVersion()
bool checkObject(const std::map< std::string, UniValue::VType > &memberTypes) const
Definition: univalue.cpp:179
256-bit opaque blob.
Definition: uint256.h:122
CTxDestination DecodeDestination(const std::string &str)
Definition: key_io.cpp:214
ArgsManager gArgs
Definition: util.cpp:88
void SetupChainParamsBaseOptions()
Set the arguments for chainparams.
bool IsSwitchChar(char c)
Definition: util.h:104
SignatureData DataFromTransaction(const CMutableTransaction &tx, unsigned int nIn, const CTxOut &txout)
Extract signature data from a transaction input, and insert it.
Definition: sign.cpp:337
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:384
uint32_t nSequence
Definition: transaction.h:66
void AddArg(const std::string &name, const std::string &help, const bool debug_only, const OptionsCategory &cat)
Add argument.
Definition: util.cpp:572
A virtual base class for key stores.
Definition: keystore.h:19
void UpdateInput(CTxIn &input, const SignatureData &data)
Definition: sign.cpp:402
bool DecodeHexTx(CMutableTransaction &tx, const std::string &hex_tx, bool try_no_witness=false, bool try_witness=true)
Definition: core_read.cpp:113
std::string GetHex() const
Definition: uint256.cpp:21
std::string EncodeHexTx(const CTransaction &tx, const int serializeFlags=0)
Definition: core_write.cpp:131
bool ProduceSignature(const SigningProvider &provider, const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
Definition: sign.cpp:186
ECCVerifyHandle globalVerifyHandle
Definition: bsha3-tx.cpp:663
bool error(const char *fmt, const Args &... args)
Definition: util.h:59
A reference to a CScript: the Hash360 of its serialization (see script.h)
Definition: standard.h:22
A mutable version of CTransaction.
Definition: transaction.h:360
size_type size() const
Definition: prevector.h:293
std::string GetChainName() const
Looks for -regtest, -testnet and returns the appropriate BIP70 chain name.
Definition: util.cpp:967
void TxToUniv(const CTransaction &tx, const uint256 &hashBlock, UniValue &entry, bool include_hex=true, int serialize_flags=0)
Definition: core_write.cpp:179
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
Definition: standard.cpp:301
int flags
Definition: bsha3-tx.cpp:509
size_t size() const
Definition: univalue.h:69
bool ParseHashStr(const std::string &strHex, uint256 &result)
Parse a hex string into 256 bits.
Definition: core_read.cpp:196
An encapsulated private key.
Definition: key.h:27
The basic transaction that is broadcasted on the network and contained in blocks. ...
Definition: transaction.h:264
CKey DecodeSecret(const std::string &str)
Definition: key_io.cpp:133
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:201
void SetupEnvironment()
Definition: util.cpp:1184
CScript ParseScript(const std::string &s)
Definition: core_read.cpp:24
COutPoint prevout
Definition: transaction.h:64
CScript GetScriptForWitness(const CScript &redeemscript)
Generate a pay-to-witness script for the given redeem script.
Definition: standard.cpp:312
Basic key store, that keeps keys in an address->secret map.
Definition: keystore.h:42
bool IsPayToWitnessScriptHash() const
Definition: script.cpp:206
bool IsValid() const
Check whether this private key is valid.
Definition: key.h:93
std::vector< unsigned char > ParseHex(const char *psz)