5 #if defined(HAVE_CONFIG_H)
31 #include <boost/algorithm/string.hpp>
55 argsman.
AddArg(
"outmultisig=VALUE:REQUIRED:PUBKEYS:PUBKEY1:PUBKEY2:....[:FLAGS]",
"Add Pay To n-of-m Multi-sig output to TX. n = REQUIRED, m = PUBKEYS. "
56 "Optionally add the \"W\" flag to produce a pay-to-witness-script-hash output. "
58 argsman.
AddArg(
"outpubkey=VALUE:PUBKEY[:FLAGS]",
"Add pay-to-pubkey output to TX. "
59 "Optionally add the \"W\" flag to produce a pay-to-witness-pubkey-hash output. "
61 argsman.
AddArg(
"outscript=VALUE:SCRIPT[:FLAGS]",
"Add raw script output to TX. "
62 "Optionally add the \"W\" flag to produce a pay-to-witness-script-hash output. "
65 argsman.
AddArg(
"sign=SIGHASH-FLAGS",
"Add zero or more signatures to transaction. "
66 "This command requires JSON registers:"
67 "prevtxs=JSON object, "
68 "privatekeys=JSON object. "
84 tfm::format(std::cerr,
"Error parsing command line arguments: %s\n", error);
91 }
catch (
const std::exception& e) {
101 "Usage: bitcoin-tx [options] <hex-tx> [commands] Update hex-encoded bitcoin transaction\n" +
102 "or: bitcoin-tx [options] -create [commands] Create hex-encoded bitcoin transaction\n" +
109 tfm::format(std::cerr,
"Error: too few parameters\n");
120 if (!val.
read(rawJson)) {
121 std::string strErr =
"Cannot parse JSON for key " + key;
122 throw std::runtime_error(strErr);
131 size_t pos = strInput.find(
':');
132 if ((pos == std::string::npos) ||
134 (pos == (strInput.size() - 1)))
135 throw std::runtime_error(
"Register input requires NAME:VALUE");
137 std::string key = strInput.substr(0, pos);
138 std::string valStr = strInput.substr(pos + 1, std::string::npos);
146 size_t pos = strInput.find(
':');
147 if ((pos == std::string::npos) ||
149 (pos == (strInput.size() - 1)))
150 throw std::runtime_error(
"Register load requires NAME:FILENAME");
152 std::string key = strInput.substr(0, pos);
153 std::string filename = strInput.substr(pos + 1, std::string::npos);
155 FILE *f =
fopen(filename.c_str(),
"r");
157 std::string strErr =
"Cannot open file " + filename;
158 throw std::runtime_error(strErr);
163 while ((!feof(f)) && (!ferror(f))) {
165 int bread = fread(buf, 1,
sizeof(buf), f);
169 valStr.insert(valStr.size(), buf, bread);
172 int error = ferror(f);
176 std::string strErr =
"Error reading file " + filename;
177 throw std::runtime_error(strErr);
188 throw std::runtime_error(
"invalid TX output value");
196 throw std::runtime_error(
"Invalid TX version requested: '" + cmdVal +
"'");
204 if (!
ParseInt64(cmdVal, &newLocktime) || newLocktime < 0LL || newLocktime > 0xffffffffLL)
205 throw std::runtime_error(
"Invalid TX locktime requested: '" + cmdVal +
"'");
207 tx.
nLockTime = (
unsigned int) newLocktime;
214 if (!
ParseInt64(strInIdx, &inIdx) || inIdx < 0 || inIdx >= static_cast<int64_t>(tx.
vin.size())) {
215 throw std::runtime_error(
"Invalid TX input index '" + strInIdx +
"'");
221 if (strInIdx ==
"" || cnt == inIdx) {
232 std::vector<std::string> vStrInputParts;
233 boost::split(vStrInputParts, strInput, boost::is_any_of(
":"));
236 if (vStrInputParts.size()<2)
237 throw std::runtime_error(
"TX input missing separator");
242 throw std::runtime_error(
"invalid TX input txid");
245 static const unsigned int minTxOutSz = 9;
249 const std::string& strVout = vStrInputParts[1];
251 if (!
ParseInt64(strVout, &vout) || vout < 0 || vout >
static_cast<int64_t
>(maxVout))
252 throw std::runtime_error(
"invalid TX input vout '" + strVout +
"'");
256 if (vStrInputParts.size() > 2)
257 nSequenceIn = std::stoul(vStrInputParts[2]);
261 tx.
vin.push_back(txin);
267 std::vector<std::string> vStrInputParts;
268 boost::split(vStrInputParts, strInput, boost::is_any_of(
":"));
270 if (vStrInputParts.size() != 2)
271 throw std::runtime_error(
"TX output missing or too many separators");
277 std::string strAddr = vStrInputParts[1];
280 throw std::runtime_error(
"invalid TX output address");
285 CTxOut txout(value, scriptPubKey);
286 tx.
vout.push_back(txout);
292 std::vector<std::string> vStrInputParts;
293 boost::split(vStrInputParts, strInput, boost::is_any_of(
":"));
295 if (vStrInputParts.size() < 2 || vStrInputParts.size() > 3)
296 throw std::runtime_error(
"TX output missing or too many separators");
303 if (!pubkey.IsFullyValid())
304 throw std::runtime_error(
"invalid TX output pubkey");
308 bool bSegWit =
false;
309 bool bScriptHash =
false;
310 if (vStrInputParts.size() == 3) {
311 std::string
flags = vStrInputParts[2];
312 bSegWit = (flags.find(
'W') != std::string::npos);
313 bScriptHash = (flags.find(
'S') != std::string::npos);
317 if (!pubkey.IsCompressed()) {
318 throw std::runtime_error(
"Uncompressed pubkeys are not useable for SegWit outputs");
329 CTxOut txout(value, scriptPubKey);
330 tx.
vout.push_back(txout);
336 std::vector<std::string> vStrInputParts;
337 boost::split(vStrInputParts, strInput, boost::is_any_of(
":"));
340 if (vStrInputParts.size()<3)
341 throw std::runtime_error(
"Not enough multisig parameters");
347 uint32_t required = stoul(vStrInputParts[1]);
350 uint32_t numkeys = stoul(vStrInputParts[2]);
353 if (vStrInputParts.size() < numkeys + 3)
354 throw std::runtime_error(
"incorrect number of multisig pubkeys");
357 throw std::runtime_error(
"multisig parameter mismatch. Required " \
361 std::vector<CPubKey> pubkeys;
362 for(
int pos = 1; pos <= int(numkeys); pos++) {
364 if (!pubkey.IsFullyValid())
365 throw std::runtime_error(
"invalid TX output pubkey");
366 pubkeys.push_back(pubkey);
370 bool bSegWit =
false;
371 bool bScriptHash =
false;
372 if (vStrInputParts.size() == numkeys + 4) {
373 std::string
flags = vStrInputParts.back();
374 bSegWit = (flags.find(
'W') != std::string::npos);
375 bScriptHash = (flags.find(
'S') != std::string::npos);
377 else if (vStrInputParts.size() > numkeys + 4) {
379 throw std::runtime_error(
"Too many parameters");
385 for (
const CPubKey& pubkey : pubkeys) {
386 if (!pubkey.IsCompressed()) {
387 throw std::runtime_error(
"Uncompressed pubkeys are not useable for SegWit outputs");
403 CTxOut txout(value, scriptPubKey);
404 tx.
vout.push_back(txout);
412 size_t pos = strInput.find(
':');
415 throw std::runtime_error(
"TX output value not specified");
417 if (pos != std::string::npos) {
423 std::string strData = strInput.substr(pos + 1, std::string::npos);
426 throw std::runtime_error(
"invalid TX output data");
428 std::vector<unsigned char> data =
ParseHex(strData);
431 tx.
vout.push_back(txout);
437 std::vector<std::string> vStrInputParts;
438 boost::split(vStrInputParts, strInput, boost::is_any_of(
":"));
439 if (vStrInputParts.size() < 2)
440 throw std::runtime_error(
"TX output missing separator");
446 std::string strScript = vStrInputParts[1];
450 bool bSegWit =
false;
451 bool bScriptHash =
false;
452 if (vStrInputParts.size() == 3) {
453 std::string
flags = vStrInputParts.back();
454 bSegWit = (flags.find(
'W') != std::string::npos);
455 bScriptHash = (flags.find(
'S') != std::string::npos);
460 "script exceeds size limit: %d > %d", scriptPubKey.size(),
MAX_SCRIPT_SIZE));
475 CTxOut txout(value, scriptPubKey);
476 tx.
vout.push_back(txout);
483 if (!
ParseInt64(strInIdx, &inIdx) || inIdx < 0 || inIdx >= static_cast<int64_t>(tx.
vin.size())) {
484 throw std::runtime_error(
"Invalid TX input index '" + strInIdx +
"'");
488 tx.
vin.erase(tx.
vin.begin() + inIdx);
495 if (!
ParseInt64(strOutIdx, &outIdx) || outIdx < 0 || outIdx >= static_cast<int64_t>(tx.
vout.size())) {
496 throw std::runtime_error(
"Invalid TX output index '" + strOutIdx +
"'");
500 tx.
vout.erase(tx.
vout.begin() + outIdx);
504 static const struct {
533 throw std::runtime_error(
"Amount is not a number or string");
536 throw std::runtime_error(
"Invalid amount");
538 throw std::runtime_error(
"Amount out of range");
546 if (flagStr.size() > 0)
548 throw std::runtime_error(
"unknown sighash flag/sign option");
558 throw std::runtime_error(
"privatekeys register variable must be set.");
562 for (
unsigned int kidx = 0; kidx < keysObj.
size(); kidx++) {
563 if (!keysObj[kidx].isStr())
564 throw std::runtime_error(
"privatekey not a std::string");
566 if (!key.IsValid()) {
567 throw std::runtime_error(
"privatekey not valid");
574 throw std::runtime_error(
"prevtxs register variable must be set.");
577 for (
unsigned int previdx = 0; previdx < prevtxsObj.
size(); previdx++) {
578 UniValue prevOut = prevtxsObj[previdx];
580 throw std::runtime_error(
"expected prevtxs internal object");
582 std::map<std::string, UniValue::VType> types = {
588 throw std::runtime_error(
"prevtxs internal object typecheck fail");
592 throw std::runtime_error(
"txid must be hexadecimal string (not '" + prevOut[
"txid"].get_str() +
"')");
595 const int nOut = prevOut[
"vout"].
get_int();
597 throw std::runtime_error(
"vout cannot be negative");
600 std::vector<unsigned char> pkData(
ParseHexUV(prevOut[
"scriptPubKey"],
"scriptPubKey"));
601 CScript scriptPubKey(pkData.begin(), pkData.end());
606 std::string err(
"Previous output scriptPubKey mismatch:\n");
609 throw std::runtime_error(err);
614 if (prevOut.
exists(
"amount")) {
618 view.
AddCoin(out, std::move(newcoin),
true);
623 if ((scriptPubKey.IsPayToScriptHash() || scriptPubKey.IsPayToWitnessScriptHash()) &&
624 prevOut.
exists(
"redeemScript")) {
625 UniValue v = prevOut[
"redeemScript"];
626 std::vector<unsigned char> rsData(
ParseHexUV(v,
"redeemScript"));
627 CScript redeemScript(rsData.begin(), rsData.end());
638 for (
unsigned int i = 0; i < mergedTx.vin.size(); i++) {
639 CTxIn& txin = mergedTx.vin[i];
649 if (!fHashSingle || (i < mergedTx.vout.size()))
672 const std::string& commandVal)
674 std::unique_ptr<Secp256k1Init> ecc;
676 if (command ==
"nversion")
678 else if (command ==
"locktime")
680 else if (command ==
"replaceable") {
684 else if (command ==
"delin")
686 else if (command ==
"in")
689 else if (command ==
"delout")
691 else if (command ==
"outaddr")
693 else if (command ==
"outpubkey") {
696 }
else if (command ==
"outmultisig") {
699 }
else if (command ==
"outscript")
701 else if (command ==
"outdata")
704 else if (command ==
"sign") {
709 else if (command ==
"load")
712 else if (command ==
"set")
716 throw std::runtime_error(
"unknown command");
724 std::string jsonOutput = entry.
write(4);
757 while (!feof(stdin)) {
758 size_t bread = fread(buf, 1,
sizeof(buf), stdin);
759 ret.append(buf, bread);
760 if (bread <
sizeof(buf))
765 throw std::runtime_error(
"error reading stdin");
767 boost::algorithm::trim_right(ret);
774 std::string strPrint;
790 throw std::runtime_error(
"too few parameters");
793 std::string strHexTx(argv[1]);
798 throw std::runtime_error(
"invalid transaction encoding");
804 for (
int i = startArg; i < argc; i++) {
805 std::string arg = argv[i];
806 std::string key, value;
807 size_t eqpos = arg.find(
'=');
808 if (eqpos == std::string::npos)
811 key = arg.substr(0, eqpos);
812 value = arg.substr(eqpos + 1);
820 catch (
const std::exception& e) {
821 strPrint = std::string(
"error: ") + e.what();
829 if (strPrint !=
"") {
830 tfm::format(nRet == 0 ? std::cout : std::cerr,
"%s\n", strPrint);
835 int main(
int argc,
char* argv[])
844 catch (
const std::exception& e) {
852 int ret = EXIT_FAILURE;
856 catch (
const std::exception& e) {
int main(int argc, char *argv[])
std::vector< unsigned char > ParseHexUV(const UniValue &v, const std::string &strName)
static void MutateTxAddOutScript(CMutableTransaction &tx, const std::string &strInput)
static std::map< std::string, UniValue > registers
static const int MAX_PUBKEYS_PER_MULTISIG
void ECC_Start()
Initialize the elliptic curve support.
static void MutateTxAddOutAddr(CMutableTransaction &tx, const std::string &strInput)
void SetupChainParamsBaseOptions(ArgsManager &argsman)
Set the arguments for chainparams.
static const int32_t MAX_STANDARD_VERSION
static void MutateTxAddOutMultiSig(CMutableTransaction &tx, const std::string &strInput)
static const uint32_t MAX_BIP125_RBF_SEQUENCE
static const int WITNESS_SCALE_FACTOR
FILE * fopen(const fs::path &p, const char *mode)
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
bool read(const char *raw, size_t len)
static void MutateTxVersion(CMutableTransaction &tx, const std::string &cmdVal)
static const uint32_t SEQUENCE_FINAL
virtual bool AddCScript(const CScript &redeemScript)
std::string GetHex() const
bool MoneyRange(const CAmount &nValue)
std::vector< unsigned char > ParseHex(const char *psz)
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
CTxOut out
unspent transaction output
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
static void MutateTxAddOutData(CMutableTransaction &tx, const std::string &strInput)
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
NODISCARD bool ParseParameters(int argc, const char *const argv[], std::string &error)
const std::function< std::string(const char *)> G_TRANSLATION_FUN
Translate string to current locale using Qt.
static void RegisterLoad(const std::string &strInput)
A signature creator for transactions.
static void MutateTxLocktime(CMutableTransaction &tx, const std::string &cmdVal)
bool ParseMoney(const std::string &money_string, CAmount &nRet)
Parse an amount denoted in full coins.
static void RegisterSetJson(const std::string &key, const std::string &rawJson)
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
static CAmount ExtractAndValidateValue(const std::string &strValue)
static void OutputTxHex(const CTransaction &tx)
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.
static const unsigned int MAX_BLOCK_WEIGHT
The maximum allowed weight for a block, see BIP 141 (network rule)
int64_t CAmount
Amount in satoshis (Can be negative)
static void MutateTxSign(CMutableTransaction &tx, const std::string &flagStr)
uint32_t nHeight
at which height this containing transaction was included in the active block chain ...
std::string ToString(const T &t)
Locale-independent version of std::to_string.
static const unsigned int N_SIGHASH_OPTS
Users of this module must hold an ECCVerifyHandle.
bool error(const char *fmt, const Args &...args)
static void MutateTxDelInput(CMutableTransaction &tx, const std::string &strInIdx)
std::string ScriptToAsmStr(const CScript &script, const bool fAttemptSighashDecode=false)
Create the assembly string representation of a CScript object.
static CAmount AmountFromValue(const UniValue &value)
static void SetupBitcoinTxArgs(ArgsManager &argsman)
Abstract view on the open txout dataset.
An input of a transaction.
void ECC_Stop()
Deinitialize the elliptic curve support.
static int AppInitRawTx(int argc, char *argv[])
void SelectParams(const std::string &network)
Sets the params returned by Params() to those for the given chain name.
static void MutateTxRBFOptIn(CMutableTransaction &tx, const std::string &strInIdx)
An encapsulated public key.
Fillable signing provider that keeps keys in an address->secret map.
bool IsHex(const std::string &str)
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
bool HelpRequested(const ArgsManager &args)
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
An output of a transaction.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
static const int MAX_SCRIPT_SIZE
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
An outpoint - a combination of a transaction hash and an index n into its vout.
std::vector< CTxOut > vout
void AddCoin(const COutPoint &outpoint, Coin &&coin, bool possible_overwrite)
Add a coin.
std::string FormatFullVersion()
static bool findSighashFlags(int &flags, const std::string &flagStr)
CTxDestination DecodeDestination(const std::string &str)
static void OutputTx(const CTransaction &tx)
const std::string & getValStr() const
static std::string readStdin()
SignatureData DataFromTransaction(const CMutableTransaction &tx, unsigned int nIn, const CTxOut &txout)
Extract signature data from a transaction input, and insert it.
Serialized script, used inside transaction inputs and outputs.
static void MutateTxAddOutPubKey(CMutableTransaction &tx, const std::string &strInput)
static void MutateTx(CMutableTransaction &tx, const std::string &command, const std::string &commandVal)
std::string GetHelpMessage() const
Get the help string.
static int CommandLineRawTx(int argc, char *argv[])
void UpdateInput(CTxIn &input, const SignatureData &data)
std::string EncodeHexTx(const CTransaction &tx, const int serializeFlags=0)
void SetupHelpOptions(ArgsManager &args)
Add help options to the args manager.
bool ProduceSignature(const SigningProvider &provider, const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
ECCVerifyHandle globalVerifyHandle
static void RegisterSet(const std::string &strInput)
A mutable version of CTransaction.
const uint256 & GetHash() const
void TxToUniv(const CTransaction &tx, const uint256 &hashBlock, UniValue &entry, bool include_hex=true, int serialize_flags=0)
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
bool checkObject(const std::map< std::string, UniValue::VType > &memberTypes) const
std::string GetChainName() const
Returns the appropriate chain name from the program arguments.
bool IsSwitchChar(char c)
bool exists(const std::string &key) const
bool ParseHashStr(const std::string &strHex, uint256 &result)
Parse a hex string into 256 bits.
An encapsulated private key.
The basic transaction that is broadcasted on the network and contained in blocks. ...
CKey DecodeSecret(const std::string &str)
CCoinsView that adds a memory cache for transactions to another CCoinsView.
static const struct @0 sighashOptions[N_SIGHASH_OPTS]
boost::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
static const int CONTINUE_EXECUTION
CScript ParseScript(const std::string &s)
static void MutateTxDelOutput(CMutableTransaction &tx, const std::string &strOutIdx)
static void OutputTxHash(const CTransaction &tx)
virtual bool AddKey(const CKey &key)
static void MutateTxAddInput(CMutableTransaction &tx, const std::string &strInput)
static void OutputTxJSON(const CTransaction &tx)
NODISCARD bool DecodeHexTx(CMutableTransaction &tx, const std::string &hex_tx, bool try_no_witness=false, bool try_witness=true)