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