5 #if defined(HAVE_CONFIG_H)
60 argsman.
AddArg(
"outmultisig=VALUE:REQUIRED:PUBKEYS:PUBKEY1:PUBKEY2:....[:FLAGS]",
"Add Pay To n-of-m Multi-sig output to TX. n = REQUIRED, m = PUBKEYS. "
61 "Optionally add the \"W\" flag to produce a pay-to-witness-script-hash output. "
63 argsman.
AddArg(
"outpubkey=VALUE:PUBKEY[:FLAGS]",
"Add pay-to-pubkey output to TX. "
64 "Optionally add the \"W\" flag to produce a pay-to-witness-pubkey-hash output. "
66 argsman.
AddArg(
"outscript=VALUE:SCRIPT[:FLAGS]",
"Add raw script output to TX. "
67 "Optionally add the \"W\" flag to produce a pay-to-witness-script-hash output. "
70 argsman.
AddArg(
"sign=SIGHASH-FLAGS",
"Add zero or more signatures to transaction. "
71 "This command requires JSON registers:"
72 "prevtxs=JSON object, "
73 "privatekeys=JSON object. "
96 }
catch (
const std::exception& e) {
111 "Usage: bitcoin-tx [options] <hex-tx> [commands] Update hex-encoded bitcoin transaction\n"
112 "or: bitcoin-tx [options] -create [commands] Create hex-encoded bitcoin transaction\n"
120 tfm::format(std::cerr,
"Error: too few parameters\n");
131 if (!val.
read(rawJson)) {
132 std::string strErr =
"Cannot parse JSON for key " + key;
133 throw std::runtime_error(strErr);
142 size_t pos = strInput.find(
':');
143 if ((pos == std::string::npos) ||
145 (pos == (strInput.size() - 1)))
146 throw std::runtime_error(
"Register input requires NAME:VALUE");
148 std::string key = strInput.substr(0, pos);
149 std::string valStr = strInput.substr(pos + 1, std::string::npos);
157 size_t pos = strInput.find(
':');
158 if ((pos == std::string::npos) ||
160 (pos == (strInput.size() - 1)))
161 throw std::runtime_error(
"Register load requires NAME:FILENAME");
163 std::string key = strInput.substr(0, pos);
164 std::string filename = strInput.substr(pos + 1, std::string::npos);
168 std::string strErr =
"Cannot open file " + filename;
169 throw std::runtime_error(strErr);
174 while ((!feof(f)) && (!ferror(f))) {
176 int bread = fread(buf, 1,
sizeof(buf), f);
180 valStr.insert(valStr.size(), buf, bread);
183 int error = ferror(f);
187 std::string strErr =
"Error reading file " + filename;
188 throw std::runtime_error(strErr);
197 if (std::optional<CAmount> parsed =
ParseMoney(strValue)) {
198 return parsed.value();
200 throw std::runtime_error(
"invalid TX output value");
208 throw std::runtime_error(
"Invalid TX version requested: '" + cmdVal +
"'");
217 if (!
ParseInt64(cmdVal, &newLocktime) || newLocktime < 0LL || newLocktime > 0xffffffffLL)
218 throw std::runtime_error(
"Invalid TX locktime requested: '" + cmdVal +
"'");
220 tx.
nLockTime = (
unsigned int) newLocktime;
227 if (!
ParseInt64(strInIdx, &inIdx) || inIdx < 0 || inIdx >=
static_cast<int64_t
>(tx.
vin.size())) {
228 throw std::runtime_error(
"Invalid TX input index '" + strInIdx +
"'");
234 if (strInIdx ==
"" || cnt == inIdx) {
243 template <
typename T>
247 if (!parsed.has_value()) {
248 throw std::runtime_error(err +
" '" + int_str +
"'");
250 return parsed.value();
255 std::vector<std::string> vStrInputParts =
SplitString(strInput,
':');
258 if (vStrInputParts.size()<2)
259 throw std::runtime_error(
"TX input missing separator");
264 throw std::runtime_error(
"invalid TX input txid");
267 static const unsigned int minTxOutSz = 9;
271 const std::string& strVout = vStrInputParts[1];
273 if (!
ParseInt64(strVout, &vout) || vout < 0 || vout >
static_cast<int64_t
>(maxVout))
274 throw std::runtime_error(
"invalid TX input vout '" + strVout +
"'");
278 if (vStrInputParts.size() > 2) {
279 nSequenceIn = TrimAndParse<uint32_t>(vStrInputParts.at(2),
"invalid TX sequence id");
284 tx.
vin.push_back(txin);
290 std::vector<std::string> vStrInputParts =
SplitString(strInput,
':');
292 if (vStrInputParts.size() != 2)
293 throw std::runtime_error(
"TX output missing or too many separators");
299 std::string strAddr = vStrInputParts[1];
302 throw std::runtime_error(
"invalid TX output address");
307 CTxOut txout(value, scriptPubKey);
308 tx.
vout.push_back(txout);
314 std::vector<std::string> vStrInputParts =
SplitString(strInput,
':');
316 if (vStrInputParts.size() < 2 || vStrInputParts.size() > 3)
317 throw std::runtime_error(
"TX output missing or too many separators");
325 throw std::runtime_error(
"invalid TX output pubkey");
329 bool bSegWit =
false;
330 bool bScriptHash =
false;
331 if (vStrInputParts.size() == 3) {
332 std::string
flags = vStrInputParts[2];
333 bSegWit = (
flags.find(
'W') != std::string::npos);
334 bScriptHash = (
flags.find(
'S') != std::string::npos);
339 throw std::runtime_error(
"Uncompressed pubkeys are not useable for SegWit outputs");
350 CTxOut txout(value, scriptPubKey);
351 tx.
vout.push_back(txout);
357 std::vector<std::string> vStrInputParts =
SplitString(strInput,
':');
360 if (vStrInputParts.size()<3)
361 throw std::runtime_error(
"Not enough multisig parameters");
367 const uint32_t required{TrimAndParse<uint32_t>(vStrInputParts.at(1),
"invalid multisig required number")};
370 const uint32_t numkeys{TrimAndParse<uint32_t>(vStrInputParts.at(2),
"invalid multisig total number")};
373 if (vStrInputParts.size() < numkeys + 3)
374 throw std::runtime_error(
"incorrect number of multisig pubkeys");
377 throw std::runtime_error(
"multisig parameter mismatch. Required " \
381 std::vector<CPubKey> pubkeys;
382 for(
int pos = 1; pos <= int(numkeys); pos++) {
385 throw std::runtime_error(
"invalid TX output pubkey");
386 pubkeys.push_back(pubkey);
390 bool bSegWit =
false;
391 bool bScriptHash =
false;
392 if (vStrInputParts.size() == numkeys + 4) {
393 std::string
flags = vStrInputParts.back();
394 bSegWit = (
flags.find(
'W') != std::string::npos);
395 bScriptHash = (
flags.find(
'S') != std::string::npos);
397 else if (vStrInputParts.size() > numkeys + 4) {
399 throw std::runtime_error(
"Too many parameters");
405 for (
const CPubKey& pubkey : pubkeys) {
406 if (!pubkey.IsCompressed()) {
407 throw std::runtime_error(
"Uncompressed pubkeys are not useable for SegWit outputs");
423 CTxOut txout(value, scriptPubKey);
424 tx.
vout.push_back(txout);
432 size_t pos = strInput.find(
':');
435 throw std::runtime_error(
"TX output value not specified");
437 if (pos == std::string::npos) {
446 const std::string strData{strInput.substr(pos, std::string::npos)};
449 throw std::runtime_error(
"invalid TX output data");
451 std::vector<unsigned char> data =
ParseHex(strData);
454 tx.
vout.push_back(txout);
460 std::vector<std::string> vStrInputParts =
SplitString(strInput,
':');
461 if (vStrInputParts.size() < 2)
462 throw std::runtime_error(
"TX output missing separator");
468 std::string strScript = vStrInputParts[1];
472 bool bSegWit =
false;
473 bool bScriptHash =
false;
474 if (vStrInputParts.size() == 3) {
475 std::string
flags = vStrInputParts.back();
476 bSegWit = (
flags.find(
'W') != std::string::npos);
477 bScriptHash = (
flags.find(
'S') != std::string::npos);
497 CTxOut txout(value, scriptPubKey);
498 tx.
vout.push_back(txout);
505 if (!
ParseInt64(strInIdx, &inIdx) || inIdx < 0 || inIdx >=
static_cast<int64_t
>(tx.
vin.size())) {
506 throw std::runtime_error(
"Invalid TX input index '" + strInIdx +
"'");
510 tx.
vin.erase(tx.
vin.begin() + inIdx);
517 if (!
ParseInt64(strOutIdx, &outIdx) || outIdx < 0 || outIdx >=
static_cast<int64_t
>(tx.
vout.size())) {
518 throw std::runtime_error(
"Invalid TX output index '" + strOutIdx +
"'");
522 tx.
vout.erase(tx.
vout.begin() + outIdx);
526 static const struct {
556 throw std::runtime_error(
"Amount is not a number or string");
559 throw std::runtime_error(
"Invalid amount");
561 throw std::runtime_error(
"Amount out of range");
571 throw std::runtime_error(strName +
" must be hexadecimal string (not '" + strHex +
"')");
581 throw std::runtime_error(
"unknown sighash flag/sign option");
591 throw std::runtime_error(
"privatekeys register variable must be set.");
595 for (
unsigned int kidx = 0; kidx < keysObj.
size(); kidx++) {
596 if (!keysObj[kidx].isStr())
597 throw std::runtime_error(
"privatekey not a std::string");
600 throw std::runtime_error(
"privatekey not valid");
607 throw std::runtime_error(
"prevtxs register variable must be set.");
610 for (
unsigned int previdx = 0; previdx < prevtxsObj.
size(); previdx++) {
611 const UniValue& prevOut = prevtxsObj[previdx];
613 throw std::runtime_error(
"expected prevtxs internal object");
615 std::map<std::string, UniValue::VType> types = {
621 throw std::runtime_error(
"prevtxs internal object typecheck fail");
625 throw std::runtime_error(
"txid must be hexadecimal string (not '" + prevOut[
"txid"].get_str() +
"')");
628 const int nOut = prevOut[
"vout"].
getInt<
int>();
630 throw std::runtime_error(
"vout cannot be negative");
633 std::vector<unsigned char> pkData(
ParseHexUV(prevOut[
"scriptPubKey"],
"scriptPubKey"));
634 CScript scriptPubKey(pkData.begin(), pkData.end());
639 std::string err(
"Previous output scriptPubKey mismatch:\n");
642 throw std::runtime_error(err);
647 if (prevOut.
exists(
"amount")) {
657 prevOut.
exists(
"redeemScript")) {
658 UniValue v = prevOut[
"redeemScript"];
659 std::vector<unsigned char> rsData(
ParseHexUV(v,
"redeemScript"));
660 CScript redeemScript(rsData.begin(), rsData.end());
671 for (
unsigned int i = 0; i < mergedTx.vin.size(); i++) {
672 CTxIn& txin = mergedTx.vin[i];
682 if (!fHashSingle || (i < mergedTx.vout.size()))
686 throw std::runtime_error(
strprintf(
"Missing amount for CTxOut with scriptPubKey=%s",
HexStr(prevPubKey)));
707 const std::string& commandVal)
709 std::unique_ptr<Secp256k1Init> ecc;
713 else if (
command ==
"locktime")
715 else if (
command ==
"replaceable") {
728 else if (
command ==
"outpubkey") {
731 }
else if (
command ==
"outmultisig") {
734 }
else if (
command ==
"outscript")
751 throw std::runtime_error(
"unknown command");
759 std::string jsonOutput = entry.
write(4);
792 while (!feof(stdin)) {
793 size_t bread = fread(buf, 1,
sizeof(buf), stdin);
794 ret.append(buf, bread);
795 if (bread <
sizeof(buf))
800 throw std::runtime_error(
"error reading stdin");
823 throw std::runtime_error(
"too few parameters");
826 std::string strHexTx(argv[1]);
831 throw std::runtime_error(
"invalid transaction encoding");
837 for (
int i = startArg; i < argc; i++) {
838 std::string arg = argv[i];
839 std::string key, value;
840 size_t eqpos = arg.find(
'=');
841 if (eqpos == std::string::npos)
844 key = arg.substr(0, eqpos);
845 value = arg.substr(eqpos + 1);
853 catch (
const std::exception& e) {
854 strPrint = std::string(
"error: ") + e.what();
877 catch (
const std::exception& e) {
889 catch (
const std::exception& e) {
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination corresponds to one with an address.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
static constexpr CAmount MAX_MONEY
No amount larger than this (in satoshi) is valid.
bool MoneyRange(const CAmount &nValue)
int64_t CAmount
Amount in satoshis (Can be negative)
bool HelpRequested(const ArgsManager &args)
void SetupHelpOptions(ArgsManager &args)
Add help options to the args manager.
bool IsSwitchChar(char c)
static bool findSighashFlags(int &flags, const std::string &flagStr)
static void OutputTxHash(const CTransaction &tx)
static const unsigned int N_SIGHASH_OPTS
static void MutateTxSign(CMutableTransaction &tx, const std::string &flagStr)
static const int CONTINUE_EXECUTION
static std::string readStdin()
static void OutputTxJSON(const CTransaction &tx)
static void RegisterSet(const std::string &strInput)
static void RegisterSetJson(const std::string &key, const std::string &rawJson)
static CAmount ExtractAndValidateValue(const std::string &strValue)
static void MutateTxDelOutput(CMutableTransaction &tx, const std::string &strOutIdx)
static const struct @0 sighashOptions[N_SIGHASH_OPTS]
static CAmount AmountFromValue(const UniValue &value)
static void MutateTx(CMutableTransaction &tx, const std::string &command, const std::string &commandVal)
const std::function< std::string(const char *)> G_TRANSLATION_FUN
Translate string to current locale using Qt.
static T TrimAndParse(const std::string &int_str, const std::string &err)
static void MutateTxAddOutPubKey(CMutableTransaction &tx, const std::string &strInput)
static std::vector< unsigned char > ParseHexUV(const UniValue &v, const std::string &strName)
static void MutateTxRBFOptIn(CMutableTransaction &tx, const std::string &strInIdx)
static void MutateTxAddOutData(CMutableTransaction &tx, const std::string &strInput)
static void MutateTxVersion(CMutableTransaction &tx, const std::string &cmdVal)
static void MutateTxAddOutAddr(CMutableTransaction &tx, const std::string &strInput)
static int CommandLineRawTx(int argc, char *argv[])
static void OutputTxHex(const CTransaction &tx)
static void RegisterLoad(const std::string &strInput)
static void MutateTxDelInput(CMutableTransaction &tx, const std::string &strInIdx)
static int AppInitRawTx(int argc, char *argv[])
static void MutateTxAddInput(CMutableTransaction &tx, const std::string &strInput)
static std::map< std::string, UniValue > registers
static void SetupBitcoinTxArgs(ArgsManager &argsman)
static void MutateTxAddOutMultiSig(CMutableTransaction &tx, const std::string &strInput)
static void MutateTxAddOutScript(CMutableTransaction &tx, const std::string &strInput)
static void MutateTxLocktime(CMutableTransaction &tx, const std::string &cmdVal)
static void OutputTx(const CTransaction &tx)
void SelectParams(const ChainType chain)
Sets the params returned by Params() to those for the given chain type.
void SetupChainParamsBaseOptions(ArgsManager &argsman)
Set the arguments for chainparams.
@ ALLOW_ANY
disable validation
ChainType GetChainType() const
Returns the appropriate chain type from the program arguments.
bool ParseParameters(int argc, const char *const argv[], std::string &error)
std::string GetHelpMessage() const
Get the help string.
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
CCoinsView that adds a memory cache for transactions to another CCoinsView.
void AddCoin(const COutPoint &outpoint, Coin &&coin, bool possible_overwrite)
Add a coin.
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
Abstract view on the open txout dataset.
An encapsulated private key.
bool IsValid() const
Check whether this private key is valid.
An outpoint - a combination of a transaction hash and an index n into its vout.
An encapsulated public key.
bool IsCompressed() const
Check whether this is a compressed public key.
bool IsFullyValid() const
fully validate whether this is a valid public key (more expensive than IsValid())
Serialized script, used inside transaction inputs and outputs.
bool IsPayToScriptHash() const
bool IsPayToWitnessScriptHash() const
The basic transaction that is broadcasted on the network and contained in blocks.
const Txid & GetHash() const LIFETIMEBOUND
An input of a transaction.
static const uint32_t SEQUENCE_FINAL
Setting nSequence to this value for every input in a transaction disables nLockTime/IsFinalTx().
An output of a transaction.
CTxOut out
unspent transaction output
bool IsSpent() const
Either this coin never existed (see e.g.
uint32_t nHeight
at which height this containing transaction was included in the active block chain
Fillable signing provider that keeps keys in an address->secret map.
virtual bool AddCScript(const CScript &redeemScript)
virtual bool AddKey(const CKey &key)
A signature creator for transactions.
bool checkObject(const std::map< std::string, UniValue::VType > &memberTypes) const
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
const std::string & getValStr() const
bool read(std::string_view raw)
bool exists(const std::string &key) const
std::string GetHex() const
static transaction_identifier FromUint256(const uint256 &id)
std::string FormatFullVersion()
std::string LicenseInfo()
Returns licensing information (for -version)
static const unsigned int MAX_BLOCK_WEIGHT
The maximum allowed weight for a block, see BIP 141 (network rule)
static const int WITNESS_SCALE_FACTOR
CScript ParseScript(const std::string &s)
bool ParseHashStr(const std::string &strHex, uint256 &result)
Parse a hex string into 256 bits.
std::string ScriptToAsmStr(const CScript &script, const bool fAttemptSighashDecode=false)
Create the assembly string representation of a CScript object.
std::string EncodeHexTx(const CTransaction &tx, const bool without_witness=false)
bool DecodeHexTx(CMutableTransaction &tx, const std::string &hex_tx, bool try_no_witness=false, bool try_witness=true)
void TxToUniv(const CTransaction &tx, const uint256 &block_hash, UniValue &entry, bool include_hex=true, bool without_witness=false, const CTxUndo *txundo=nullptr, TxVerbosity verbosity=TxVerbosity::SHOW_DETAILS)
void PrintExceptionContinue(const std::exception *pex, std::string_view thread_name)
#define T(expected, seed, data)
@ SIGHASH_DEFAULT
Taproot only; implied when sighash byte is missing, and equivalent to SIGHASH_ALL.
CTxDestination DecodeDestination(const std::string &str, std::string &error_msg, std::vector< int > *error_locations)
CKey DecodeSecret(const std::string &str)
bool error(const char *fmt, const Args &... args)
std::optional< CAmount > ParseMoney(const std::string &money_string)
Parse an amount denoted in full coins.
FILE * fopen(const fs::path &p, const char *mode)
static constexpr decltype(CTransaction::nVersion) TX_MAX_STANDARD_VERSION
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
static const int MAX_SCRIPT_SIZE
static const int MAX_PUBKEYS_PER_MULTISIG
bool ProduceSignature(const SigningProvider &provider, const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
void UpdateInput(CTxIn &input, const SignatureData &data)
SignatureData DataFromTransaction(const CMutableTransaction &tx, unsigned int nIn, const CTxOut &txout)
Extract signature data from a transaction input, and insert it.
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
std::string TrimString(std::string_view str, std::string_view pattern=" \f\n\r\t\v")
std::vector< std::string > SplitString(std::string_view str, char sep)
std::string ToString(const T &t)
Locale-independent version of std::to_string.
std::string_view TrimStringView(std::string_view str, std::string_view pattern=" \f\n\r\t\v")
A mutable version of CTransaction.
std::vector< CTxOut > vout
CScriptWitness scriptWitness
The scriptWitness of an input. Contains complete signatures or the traditional partial signatures for...
static constexpr uint32_t MAX_BIP125_RBF_SEQUENCE
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
bool ParseFixedPoint(std::string_view val, int decimals, int64_t *amount_out)
Parse number as fixed point according to JSON number syntax.
bool ParseInt64(std::string_view str, int64_t *out)
Convert string to signed 64-bit integer with strict parse error feedback.
bool IsHex(std::string_view str)
std::string FormatParagraph(std::string_view in, size_t width, size_t indent)
Format a paragraph of text to a fixed width, adding spaces for indentation to any added line.