5 #if defined(HAVE_CONFIG_H) 6 #include <config/dash-config.h> 27 #include <boost/algorithm/string.hpp> 54 }
catch (
const std::exception& e) {
55 fprintf(stderr,
"Error: %s\n", e.what());
66 " dash-tx [options] <hex-tx> [commands] " +
_(
"Update hex-encoded dash transaction") +
"\n" +
67 " dash-tx [options] -create [commands] " +
_(
"Create hex-encoded dash transaction") +
"\n" +
70 fprintf(stdout,
"%s", strUsage.c_str());
76 strUsage +=
HelpMessageOpt(
"-txid",
_(
"Output only the hex-encoded transaction id of the resultant transaction."));
79 fprintf(stdout,
"%s", strUsage.c_str());
84 strUsage +=
HelpMessageOpt(
"in=TXID:VOUT(:SEQUENCE_NUMBER)",
_(
"Add input to TX"));
87 strUsage +=
HelpMessageOpt(
"outaddr=VALUE:ADDRESS",
_(
"Add address-based output to TX"));
88 strUsage +=
HelpMessageOpt(
"outpubkey=VALUE:PUBKEY[:FLAGS]",
_(
"Add pay-to-pubkey output to TX") +
". " +
89 _(
"Optionally add the \"S\" flag to wrap the output in a pay-to-script-hash."));
90 strUsage +=
HelpMessageOpt(
"outdata=[VALUE:]DATA",
_(
"Add data-based output to TX"));
91 strUsage +=
HelpMessageOpt(
"outscript=VALUE:SCRIPT[:FLAGS]",
_(
"Add raw script output to TX") +
". " +
92 _(
"Optionally add the \"S\" flag to wrap the output in a pay-to-script-hash."));
93 strUsage +=
HelpMessageOpt(
"outmultisig=VALUE:REQUIRED:PUBKEYS:PUBKEY1:PUBKEY2:....[:FLAGS]",
_(
"Add Pay To n-of-m Multi-sig output to TX. n = REQUIRED, m = PUBKEYS") +
". " +
94 _(
"Optionally add the \"S\" flag to wrap the output in a pay-to-script-hash."));
95 strUsage +=
HelpMessageOpt(
"sign=SIGHASH-FLAGS",
_(
"Add zero or more signatures to transaction") +
". " +
96 _(
"This command requires JSON registers:") +
97 _(
"prevtxs=JSON object") +
", " +
98 _(
"privatekeys=JSON object") +
". " +
99 _(
"See signrawtransaction docs for format of sighash flags, JSON objects."));
100 fprintf(stdout,
"%s", strUsage.c_str());
103 strUsage +=
HelpMessageOpt(
"load=NAME:FILENAME",
_(
"Load JSON file FILENAME into register NAME"));
104 strUsage +=
HelpMessageOpt(
"set=NAME:JSON-STRING",
_(
"Set register NAME to given JSON-STRING"));
105 fprintf(stdout,
"%s", strUsage.c_str());
108 fprintf(stderr,
"Error: too few parameters\n");
119 if (!val.
read(rawJson)) {
120 std::string strErr =
"Cannot parse JSON for key " + key;
121 throw std::runtime_error(strErr);
130 size_t pos = strInput.find(
':');
131 if ((pos == std::string::npos) ||
133 (pos == (strInput.size() - 1)))
134 throw std::runtime_error(
"Register input requires NAME:VALUE");
136 std::string key = strInput.substr(0, pos);
137 std::string valStr = strInput.substr(pos + 1, std::string::npos);
145 size_t pos = strInput.find(
':');
146 if ((pos == std::string::npos) ||
148 (pos == (strInput.size() - 1)))
149 throw std::runtime_error(
"Register load requires NAME:FILENAME");
151 std::string key = strInput.substr(0, pos);
152 std::string filename = strInput.substr(pos + 1, std::string::npos);
154 FILE *f =
fopen(filename.c_str(),
"r");
156 std::string strErr =
"Cannot open file " + filename;
157 throw std::runtime_error(strErr);
162 while ((!feof(f)) && (!ferror(f))) {
164 int bread = fread(buf, 1,
sizeof(buf), f);
168 valStr.insert(valStr.size(), buf, bread);
171 int error = ferror(f);
175 std::string strErr =
"Error reading file " + filename;
176 throw std::runtime_error(strErr);
187 throw std::runtime_error(
"invalid TX output value");
193 int64_t newVersion =
atoi64(cmdVal);
195 throw std::runtime_error(
"Invalid TX version requested");
202 int64_t newLocktime =
atoi64(cmdVal);
203 if (newLocktime < 0LL || newLocktime > 0xffffffffLL)
204 throw std::runtime_error(
"Invalid TX locktime requested");
206 tx.
nLockTime = (
unsigned int) newLocktime;
211 std::vector<std::string> vStrInputParts;
212 boost::split(vStrInputParts, strInput, boost::is_any_of(
":"));
215 if (vStrInputParts.size()<2)
216 throw std::runtime_error(
"TX input missing separator");
219 std::string strTxid = vStrInputParts[0];
220 if ((strTxid.size() != 64) || !
IsHex(strTxid))
221 throw std::runtime_error(
"invalid TX input txid");
224 static const unsigned int minTxOutSz = 9;
225 static const unsigned int maxVout =
MaxBlockSize(
true) / minTxOutSz;
228 std::string strVout = vStrInputParts[1];
229 int vout =
atoi(strVout);
230 if ((vout < 0) || (vout > (
int)maxVout))
231 throw std::runtime_error(
"invalid TX input vout");
234 uint32_t nSequenceIn=std::numeric_limits<unsigned int>::max();
235 if (vStrInputParts.size() > 2)
236 nSequenceIn = std::stoul(vStrInputParts[2]);
240 tx.
vin.push_back(txin);
246 std::vector<std::string> vStrInputParts;
247 boost::split(vStrInputParts, strInput, boost::is_any_of(
":"));
249 if (vStrInputParts.size() != 2)
250 throw std::runtime_error(
"TX output missing or too many separators");
256 std::string strAddr = vStrInputParts[1];
259 throw std::runtime_error(
"invalid TX output address");
264 CTxOut txout(value, scriptPubKey);
265 tx.
vout.push_back(txout);
271 std::vector<std::string> vStrInputParts;
272 boost::split(vStrInputParts, strInput, boost::is_any_of(
":"));
274 if (vStrInputParts.size() < 2 || vStrInputParts.size() > 3)
275 throw std::runtime_error(
"TX output missing or too many separators");
283 throw std::runtime_error(
"invalid TX output pubkey");
287 bool bScriptHash =
false;
288 if (vStrInputParts.size() == 3) {
289 std::string
flags = vStrInputParts[2];
290 bScriptHash = (
flags.find(
'S') != std::string::npos);
299 CTxOut txout(value, scriptPubKey);
300 tx.
vout.push_back(txout);
306 std::vector<std::string> vStrInputParts;
307 boost::split(vStrInputParts, strInput, boost::is_any_of(
":"));
310 if (vStrInputParts.size()<3)
311 throw std::runtime_error(
"Not enough multisig parameters");
317 uint32_t required = stoul(vStrInputParts[1]);
320 uint32_t numkeys = stoul(vStrInputParts[2]);
323 if (vStrInputParts.size() < numkeys + 3)
324 throw std::runtime_error(
"incorrect number of multisig pubkeys");
326 if (required < 1 || required > 20 || numkeys < 1 || numkeys > 20 || numkeys < required)
327 throw std::runtime_error(
"multisig parameter mismatch. Required " \
328 + std::to_string(required) +
" of " + std::to_string(numkeys) +
"signatures.");
331 std::vector<CPubKey> pubkeys;
332 for(
int pos = 1; pos <= int(numkeys); pos++) {
335 throw std::runtime_error(
"invalid TX output pubkey");
336 pubkeys.push_back(pubkey);
340 bool bScriptHash =
false;
341 if (vStrInputParts.size() == numkeys + 4) {
342 std::string
flags = vStrInputParts.back();
343 bScriptHash = (
flags.find(
'S') != std::string::npos);
345 else if (vStrInputParts.size() > numkeys + 4) {
347 throw std::runtime_error(
"Too many parameters");
362 CTxOut txout(value, scriptPubKey);
363 tx.
vout.push_back(txout);
371 size_t pos = strInput.find(
':');
374 throw std::runtime_error(
"TX output value not specified");
376 if (pos != std::string::npos) {
382 std::string strData = strInput.substr(pos + 1, std::string::npos);
385 throw std::runtime_error(
"invalid TX output data");
387 std::vector<unsigned char> data =
ParseHex(strData);
390 tx.
vout.push_back(txout);
396 std::vector<std::string> vStrInputParts;
397 boost::split(vStrInputParts, strInput, boost::is_any_of(
":"));
398 if (vStrInputParts.size() < 2)
399 throw std::runtime_error(
"TX output missing separator");
405 std::string strScript = vStrInputParts[1];
409 bool bScriptHash =
false;
410 if (vStrInputParts.size() == 3) {
411 std::string
flags = vStrInputParts.back();
412 bScriptHash = (
flags.find(
'S') != std::string::npos);
429 CTxOut txout(value, scriptPubKey);
430 tx.
vout.push_back(txout);
436 int inIdx =
atoi(strInIdx);
437 if (inIdx < 0 || inIdx >= (
int)tx.
vin.size()) {
438 std::string strErr =
"Invalid TX input index '" + strInIdx +
"'";
439 throw std::runtime_error(strErr.c_str());
443 tx.
vin.erase(tx.
vin.begin() + inIdx);
449 int outIdx =
atoi(strOutIdx);
450 if (outIdx < 0 || outIdx >= (
int)tx.
vout.size()) {
451 std::string strErr =
"Invalid TX output index '" + strOutIdx +
"'";
452 throw std::runtime_error(strErr.c_str());
456 tx.
vout.erase(tx.
vout.begin() + outIdx);
460 static const struct {
489 throw std::runtime_error(
"Amount is not a number or string");
492 throw std::runtime_error(
"Invalid amount");
494 throw std::runtime_error(
"Amount out of range");
504 throw std::runtime_error(
"unknown sighash flag/sign option");
506 std::vector<CTransaction> txVariants;
507 txVariants.push_back(tx);
512 bool fComplete =
true;
517 throw std::runtime_error(
"privatekeys register variable must be set.");
521 for (
unsigned int kidx = 0; kidx < keysObj.
size(); kidx++) {
522 if (!keysObj[kidx].isStr())
523 throw std::runtime_error(
"privatekey not a std::string");
525 bool fGood = vchSecret.
SetString(keysObj[kidx].getValStr());
527 throw std::runtime_error(
"privatekey not valid");
535 throw std::runtime_error(
"prevtxs register variable must be set.");
538 for (
unsigned int previdx = 0; previdx < prevtxsObj.
size(); previdx++) {
539 UniValue prevOut = prevtxsObj[previdx];
541 throw std::runtime_error(
"expected prevtxs internal object");
543 std::map<std::string, UniValue::VType> types = {
549 throw std::runtime_error(
"prevtxs internal object typecheck fail");
553 int nOut =
atoi(prevOut[
"vout"].getValStr());
555 throw std::runtime_error(
"vout must be positive");
558 std::vector<unsigned char> pkData(
ParseHexUV(prevOut[
"scriptPubKey"],
"scriptPubKey"));
559 CScript scriptPubKey(pkData.begin(), pkData.end());
564 std::string err(
"Previous output scriptPubKey mismatch:\n");
567 throw std::runtime_error(err);
572 if (prevOut.
exists(
"amount")) {
576 view.
AddCoin(out, std::move(newcoin),
true);
581 if (scriptPubKey.IsPayToScriptHash() &&
582 prevOut.
exists(
"redeemScript")) {
583 UniValue v = prevOut[
"redeemScript"];
584 std::vector<unsigned char> rsData(
ParseHexUV(v,
"redeemScript"));
585 CScript redeemScript(rsData.begin(), rsData.end());
591 const CKeyStore& keystore = tempKeystore;
596 for (
unsigned int i = 0; i < mergedTx.
vin.size(); i++) {
608 if (!fHashSingle || (i < mergedTx.
vout.size()))
641 const std::string& commandVal)
643 std::unique_ptr<Secp256k1Init> ecc;
645 if (command ==
"nversion")
647 else if (command ==
"locktime")
650 else if (command ==
"delin")
652 else if (command ==
"in")
655 else if (command ==
"delout")
657 else if (command ==
"outaddr")
659 else if (command ==
"outpubkey") {
662 }
else if (command ==
"outmultisig") {
665 }
else if (command ==
"outscript")
667 else if (command ==
"outdata")
670 else if (command ==
"sign") {
675 else if (command ==
"load")
678 else if (command ==
"set")
682 throw std::runtime_error(
"unknown command");
690 std::string jsonOutput = entry.
write(4);
691 fprintf(stdout,
"%s\n", jsonOutput.c_str());
698 fprintf(stdout,
"%s\n", strHexHash.c_str());
705 fprintf(stdout,
"%s\n", strHex.c_str());
723 while (!feof(stdin)) {
724 size_t bread = fread(buf, 1,
sizeof(buf), stdin);
725 ret.append(buf, bread);
726 if (bread <
sizeof(buf))
731 throw std::runtime_error(
"error reading stdin");
733 boost::algorithm::trim_right(ret);
740 std::string strPrint;
756 throw std::runtime_error(
"too few parameters");
759 std::string strHexTx(argv[1]);
764 throw std::runtime_error(
"invalid transaction encoding");
770 for (
int i = startArg; i < argc; i++) {
771 std::string arg = argv[i];
772 std::string key, value;
773 size_t eqpos = arg.find(
'=');
774 if (eqpos == std::string::npos)
777 key = arg.substr(0, eqpos);
778 value = arg.substr(eqpos + 1);
787 catch (
const boost::thread_interrupted&) {
790 catch (
const std::exception& e) {
791 strPrint = std::string(
"error: ") + e.what();
799 if (strPrint !=
"") {
800 fprintf((nRet == 0 ? stdout : stderr),
"%s\n", strPrint.c_str());
805 int main(
int argc,
char* argv[])
817 catch (
const std::exception& e) {
822 int ret = EXIT_FAILURE;
static const struct @7 sighashOptions[N_SIGHASH_OPTS]
std::vector< unsigned char > ParseHexUV(const UniValue &v, const std::string &strName)
std::string HelpMessageOpt(const std::string &option, const std::string &message)
Format a string to be used as option description in help messages.
static void MutateTxAddOutAddr(CMutableTransaction &tx, const std::string &strInput)
static const int CONTINUE_EXECUTION
void UpdateTransaction(CMutableTransaction &tx, unsigned int nIn, const SignatureData &data)
void ECC_Start()
Initialize the elliptic curve support.
void AppendParamsHelpMessages(std::string &strUsage, bool debugHelp)
Append the help messages for the chainparams options to the parameter string.
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
SignatureData DataFromTransaction(const CMutableTransaction &tx, unsigned int nIn)
Extract signature data from a transaction, and insert it.
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
void AddCoin(const COutPoint &outpoint, Coin &&coin, bool potential_overwrite)
Add a coin.
static const int32_t MAX_STANDARD_VERSION
void ParseParameters(int argc, const char *const argv[])
FILE * fopen(const fs::path &p, const char *mode)
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or a pruned one if not found.
static std::string readStdin()
bool read(const char *raw, size_t len)
unsigned int MaxBlockSize(bool fDIP0001Active)
bool MoneyRange(const CAmount &nValue)
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
CTxOut out
unspent transaction output
std::string GetCrashInfoStrFromSerializedStr(const std::string &ciStr)
CTxDestination DecodeDestination(const std::string &str)
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
bool AddCScript(const CScript &redeemScript) override
Support for BIP 0013 : see https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki.
static int AppInitRawTx(int argc, char *argv[])
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
static bool findSighashFlags(int &flags, const std::string &flagStr)
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
static void OutputTxJSON(const CTransaction &tx)
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
static void MutateTxAddOutPubKey(CMutableTransaction &tx, const std::string &strInput)
const std::string & getValStr() const
static void RegisterSetJson(const std::string &key, const std::string &rawJson)
bool ProduceSignature(const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
bool DecodeHexTx(CMutableTransaction &tx, const std::string &strHexTx)
static std::map< std::string, UniValue > registers
static void MutateTxDelOutput(CMutableTransaction &tx, const std::string &strOutIdx)
static int CommandLineRawTx(int argc, char *argv[])
bool SetString(const char *pszSecret)
int64_t CAmount
Amount in satoshis (Can be negative)
uint32_t nHeight
at which height this containing transaction was included in the active block chain ...
Users of this module must hold an ECCVerifyHandle.
static void RegisterLoad(const std::string &strInput)
static void OutputTxHash(const CTransaction &tx)
std::string ScriptToAsmStr(const CScript &script, const bool fAttemptSighashDecode=false)
Create the assembly string representation of a CScript object.
bool IsFullyValid() const
fully validate whether this is a valid public key (more expensive than IsValid()) ...
Abstract view on the open txout dataset.
An input of a transaction.
void ECC_Stop()
Deinitialize the elliptic curve support.
A base58-encoded secret key.
const uint256 & GetHash() const
bool exists(const std::string &key) const
void SelectParams(const std::string &network)
Sets the params returned by Params() to those for the given BIP70 chain name.
uint256 ParseHashUV(const UniValue &v, const std::string &strName)
uint256 uint256S(const char *str)
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.
static void MutateTxAddOutMultiSig(CMutableTransaction &tx, const std::string &strInput)
bool IsHex(const std::string &str)
static void MutateTxSign(CMutableTransaction &tx, const std::string &flagStr)
int main(int argc, char *argv[])
bool ParseMoney(const std::string &str, CAmount &nRet)
An output of a transaction.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
static const int MAX_SCRIPT_SIZE
static CAmount ExtractAndValidateValue(const std::string &strValue)
An outpoint - a combination of a transaction hash and an index n into its vout.
virtual bool AddKey(const CKey &key)
void RegisterPrettyTerminateHander()
std::vector< CTxOut > vout
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
std::string FormatFullVersion()
static void MutateTx(CMutableTransaction &tx, const std::string &command, const std::string &commandVal)
bool checkObject(const std::map< std::string, UniValue::VType > &memberTypes) const
void PrintExceptionContinue(const std::exception_ptr pex, const char *pszExceptionOrigin)
static const unsigned int N_SIGHASH_OPTS
std::string EncodeHexTx(const CTransaction &tx)
bool IsSwitchChar(char c)
static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS
Standard script verification flags that standard transactions will comply with.
Serialized script, used inside transaction inputs and outputs.
static void MutateTxLocktime(CMutableTransaction &tx, const std::string &cmdVal)
static void MutateTxDelInput(CMutableTransaction &tx, const std::string &strInIdx)
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
A virtual base class for key stores.
std::string GetHex() const
static void MutateTxAddInput(CMutableTransaction &tx, const std::string &strInput)
int64_t atoi64(const char *psz)
void TxToUniv(const CTransaction &tx, const uint256 &hashBlock, UniValue &entry, bool include_hex=true, const CSpentIndexTxInfo *ptxSpentInfo=nullptr)
ECCVerifyHandle globalVerifyHandle
static Stacks CombineSignatures(const CScript &scriptPubKey, const BaseSignatureChecker &checker, const txnouttype txType, const std::vector< valtype > &vSolutions, Stacks sigs1, Stacks sigs2, SigVersion sigversion)
bool error(const char *fmt, const Args &... args)
void RegisterPrettySignalHandlers()
A reference to a CScript: the Hash160 of its serialization (see script.h)
A mutable version of CTransaction.
static void MutateTxAddOutData(CMutableTransaction &tx, const std::string &strInput)
std::string GetChainName() const
Looks for -regtest, -testnet and returns the appropriate BIP70 chain name.
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
An encapsulated private key.
The basic transaction that is broadcasted on the network and contained in blocks. ...
CCoinsView that adds a memory cache for transactions to another CCoinsView.
static CAmount AmountFromValue(const UniValue &value)
CScript ParseScript(const std::string &s)
static void OutputTxHex(const CTransaction &tx)
std::string HelpMessageGroup(const std::string &message)
Format a string to be used as group of options in help messages.
Basic key store, that keeps keys in an address->secret map.
static void MutateTxAddOutScript(CMutableTransaction &tx, const std::string &strInput)
static void OutputTx(const CTransaction &tx)
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a boost::optional result...
int atoi(const std::string &str)
static void RegisterSet(const std::string &strInput)
static void MutateTxVersion(CMutableTransaction &tx, const std::string &cmdVal)
std::vector< unsigned char > ParseHex(const char *psz)