5 #if defined(HAVE_CONFIG_H)
6 #include "config/bitcoin-config.h"
26 #include <boost/algorithm/string.hpp>
27 #include <boost/assign/list_of.hpp>
29 static bool fCreateBlank;
30 static std::map<std::string,UniValue> registers;
31 static const int CONTINUE_EXECUTION=-1;
37 static int AppInitRawTx(
int argc,
char* argv[])
47 }
catch (
const std::exception& e) {
48 fprintf(stderr,
"Error: %s\n", e.what());
59 " dogecoin-tx [options] <hex-tx> [commands] " +
_(
"Update hex-encoded dogecoin transaction") +
"\n" +
60 " dogecoin-tx [options] -create [commands] " +
_(
"Create hex-encoded dogecoin transaction") +
"\n" +
63 fprintf(stdout,
"%s", strUsage.c_str());
69 strUsage +=
HelpMessageOpt(
"-txid",
_(
"Output only the hex-encoded transaction id of the resultant transaction."));
72 fprintf(stdout,
"%s", strUsage.c_str());
77 strUsage +=
HelpMessageOpt(
"in=TXID:VOUT(:SEQUENCE_NUMBER)",
_(
"Add input to TX"));
80 strUsage +=
HelpMessageOpt(
"outaddr=VALUE:ADDRESS",
_(
"Add address-based output to TX"));
81 strUsage +=
HelpMessageOpt(
"outpubkey=VALUE:PUBKEY[:FLAGS]",
_(
"Add pay-to-pubkey output to TX") +
". " +
82 _(
"Optionally add the \"W\" flag to produce a pay-to-witness-pubkey-hash output") +
". " +
83 _(
"Optionally add the \"S\" flag to wrap the output in a pay-to-script-hash."));
84 strUsage +=
HelpMessageOpt(
"outdata=[VALUE:]DATA",
_(
"Add data-based output to TX"));
85 strUsage +=
HelpMessageOpt(
"outscript=VALUE:SCRIPT[:FLAGS]",
_(
"Add raw script output to TX") +
". " +
86 _(
"Optionally add the \"W\" flag to produce a pay-to-witness-script-hash output") +
". " +
87 _(
"Optionally add the \"S\" flag to wrap the output in a pay-to-script-hash."));
88 strUsage +=
HelpMessageOpt(
"outmultisig=VALUE:REQUIRED:PUBKEYS:PUBKEY1:PUBKEY2:....[:FLAGS]",
_(
"Add Pay To n-of-m Multi-sig output to TX. n = REQUIRED, m = PUBKEYS") +
". " +
89 _(
"Optionally add the \"W\" flag to produce a pay-to-witness-script-hash output") +
". " +
90 _(
"Optionally add the \"S\" flag to wrap the output in a pay-to-script-hash."));
91 strUsage +=
HelpMessageOpt(
"sign=SIGHASH-FLAGS",
_(
"Add zero or more signatures to transaction") +
". " +
92 _(
"This command requires JSON registers:") +
93 _(
"prevtxs=JSON object") +
", " +
94 _(
"privatekeys=JSON object") +
". " +
95 _(
"See signrawtransaction docs for format of sighash flags, JSON objects."));
96 fprintf(stdout,
"%s", strUsage.c_str());
99 strUsage +=
HelpMessageOpt(
"load=NAME:FILENAME",
_(
"Load JSON file FILENAME into register NAME"));
100 strUsage +=
HelpMessageOpt(
"set=NAME:JSON-STRING",
_(
"Set register NAME to given JSON-STRING"));
101 fprintf(stdout,
"%s", strUsage.c_str());
104 fprintf(stderr,
"Error: too few parameters\n");
109 return CONTINUE_EXECUTION;
112 static void RegisterSetJson(
const std::string& key,
const std::string& rawJson)
115 if (!val.
read(rawJson)) {
116 std::string strErr =
"Cannot parse JSON for key " + key;
117 throw std::runtime_error(strErr);
120 registers[key] = val;
123 static void RegisterSet(
const std::string& strInput)
126 size_t pos = strInput.find(
':');
127 if ((pos == std::string::npos) ||
129 (pos == (strInput.size() - 1)))
130 throw std::runtime_error(
"Register input requires NAME:VALUE");
132 std::string key = strInput.substr(0, pos);
133 std::string valStr = strInput.substr(pos + 1, std::string::npos);
135 RegisterSetJson(key, valStr);
138 static void RegisterLoad(
const std::string& strInput)
141 size_t pos = strInput.find(
':');
142 if ((pos == std::string::npos) ||
144 (pos == (strInput.size() - 1)))
145 throw std::runtime_error(
"Register load requires NAME:FILENAME");
147 std::string key = strInput.substr(0, pos);
148 std::string filename = strInput.substr(pos + 1, std::string::npos);
150 FILE *f = fopen(filename.c_str(),
"r");
152 std::string strErr =
"Cannot open file " + filename;
153 throw std::runtime_error(strErr);
158 while ((!feof(f)) && (!ferror(f))) {
160 int bread = fread(buf, 1,
sizeof(buf), f);
164 valStr.insert(valStr.size(), buf, bread);
167 int error = ferror(f);
171 std::string strErr =
"Error reading file " + filename;
172 throw std::runtime_error(strErr);
176 RegisterSetJson(key, valStr);
179 static CAmount ExtractAndValidateValue(
const std::string& strValue)
183 throw std::runtime_error(
"invalid TX output value");
189 int64_t newVersion =
atoi64(cmdVal);
191 throw std::runtime_error(
"Invalid TX version requested");
198 int64_t newLocktime =
atoi64(cmdVal);
199 if (newLocktime < 0LL || newLocktime > 0xffffffffLL)
200 throw std::runtime_error(
"Invalid TX locktime requested");
202 tx.
nLockTime = (
unsigned int) newLocktime;
207 std::vector<std::string> vStrInputParts;
208 boost::split(vStrInputParts, strInput, boost::is_any_of(
":"));
211 if (vStrInputParts.size()<2)
212 throw std::runtime_error(
"TX input missing separator");
215 std::string strTxid = vStrInputParts[0];
216 if ((strTxid.size() != 64) || !
IsHex(strTxid))
217 throw std::runtime_error(
"invalid TX input txid");
220 static const unsigned int minTxOutSz = 9;
221 static const unsigned int maxVout = MAX_BLOCK_BASE_SIZE / minTxOutSz;
224 std::string strVout = vStrInputParts[1];
225 int vout =
atoi(strVout);
226 if ((vout < 0) || (vout > (
int)maxVout))
227 throw std::runtime_error(
"invalid TX input vout");
230 uint32_t nSequenceIn=std::numeric_limits<unsigned int>::max();
231 if (vStrInputParts.size() > 2)
232 nSequenceIn = std::stoul(vStrInputParts[2]);
236 tx.
vin.push_back(txin);
242 std::vector<std::string> vStrInputParts;
243 boost::split(vStrInputParts, strInput, boost::is_any_of(
":"));
245 if (vStrInputParts.size() != 2)
246 throw std::runtime_error(
"TX output missing or too many separators");
249 CAmount value = ExtractAndValidateValue(vStrInputParts[0]);
252 std::string strAddr = vStrInputParts[1];
255 throw std::runtime_error(
"invalid TX output address");
260 CTxOut txout(value, scriptPubKey);
261 tx.
vout.push_back(txout);
267 std::vector<std::string> vStrInputParts;
268 boost::split(vStrInputParts, strInput, boost::is_any_of(
":"));
270 if (vStrInputParts.size() < 2 || vStrInputParts.size() > 3)
271 throw std::runtime_error(
"TX output missing or too many separators");
274 CAmount value = ExtractAndValidateValue(vStrInputParts[0]);
278 if (!pubkey.IsFullyValid())
279 throw std::runtime_error(
"invalid TX output pubkey");
284 bool bSegWit =
false;
285 bool bScriptHash =
false;
286 if (vStrInputParts.size() == 3) {
287 std::string
flags = vStrInputParts[2];
288 bSegWit = (
flags.find(
"W") != std::string::npos);
289 bScriptHash = (
flags.find(
"S") != std::string::npos);
304 CTxOut txout(value, scriptPubKey);
305 tx.
vout.push_back(txout);
311 std::vector<std::string> vStrInputParts;
312 boost::split(vStrInputParts, strInput, boost::is_any_of(
":"));
315 if (vStrInputParts.size()<3)
316 throw std::runtime_error(
"Not enough multisig parameters");
319 CAmount value = ExtractAndValidateValue(vStrInputParts[0]);
322 uint32_t required = stoul(vStrInputParts[1]);
325 uint32_t numkeys = stoul(vStrInputParts[2]);
328 if (vStrInputParts.size() < numkeys + 3)
329 throw std::runtime_error(
"incorrect number of multisig pubkeys");
331 if (required < 1 || required > 20 || numkeys < 1 || numkeys > 20 || numkeys < required)
332 throw std::runtime_error(
"multisig parameter mismatch. Required " \
333 + std::to_string(required) +
" of " + std::to_string(numkeys) +
"signatures.");
336 std::vector<CPubKey> pubkeys;
337 for(
int pos = 1; pos <= int(numkeys); pos++) {
339 if (!pubkey.IsFullyValid())
340 throw std::runtime_error(
"invalid TX output pubkey");
341 pubkeys.push_back(pubkey);
345 bool bSegWit =
false;
346 bool bScriptHash =
false;
347 if (vStrInputParts.size() == numkeys + 4) {
348 std::string
flags = vStrInputParts.back();
349 bSegWit = (
flags.find(
"W") != std::string::npos);
350 bScriptHash = (
flags.find(
"S") != std::string::npos);
352 else if (vStrInputParts.size() > numkeys + 4) {
354 throw std::runtime_error(
"Too many parameters");
371 CTxOut txout(value, scriptPubKey);
372 tx.
vout.push_back(txout);
380 size_t pos = strInput.find(
':');
383 throw std::runtime_error(
"TX output value not specified");
385 if (pos != std::string::npos) {
387 value = ExtractAndValidateValue(strInput.substr(0, pos));
391 std::string strData = strInput.substr(pos + 1, std::string::npos);
394 throw std::runtime_error(
"invalid TX output data");
396 std::vector<unsigned char> data =
ParseHex(strData);
399 tx.
vout.push_back(txout);
405 std::vector<std::string> vStrInputParts;
406 boost::split(vStrInputParts, strInput, boost::is_any_of(
":"));
407 if (vStrInputParts.size() < 2)
408 throw std::runtime_error(
"TX output missing separator");
411 CAmount value = ExtractAndValidateValue(vStrInputParts[0]);
414 std::string strScript = vStrInputParts[1];
418 bool bSegWit =
false;
419 bool bScriptHash =
false;
420 if (vStrInputParts.size() == 3) {
421 std::string
flags = vStrInputParts.back();
422 bSegWit = (
flags.find(
"W") != std::string::npos);
423 bScriptHash = (
flags.find(
"S") != std::string::npos);
435 CTxOut txout(value, scriptPubKey);
436 tx.
vout.push_back(txout);
442 int inIdx =
atoi(strInIdx);
443 if (inIdx < 0 || inIdx >= (
int)tx.
vin.size()) {
444 std::string strErr =
"Invalid TX input index '" + strInIdx +
"'";
445 throw std::runtime_error(strErr.c_str());
449 tx.
vin.erase(tx.
vin.begin() + inIdx);
455 int outIdx =
atoi(strOutIdx);
456 if (outIdx < 0 || outIdx >= (
int)tx.
vout.size()) {
457 std::string strErr =
"Invalid TX output index '" + strOutIdx +
"'";
458 throw std::runtime_error(strErr.c_str());
462 tx.
vout.erase(tx.
vout.begin() + outIdx);
465 static const unsigned int N_SIGHASH_OPTS = 6;
466 static const struct {
469 } sighashOptions[N_SIGHASH_OPTS] = {
478 static bool findSighashFlags(
int&
flags,
const std::string&
flagStr)
482 for (
unsigned int i = 0; i < N_SIGHASH_OPTS; i++) {
484 flags = sighashOptions[i].flags;
494 if (!o.count(strKey))
499 std::vector<unsigned char>
ParseHexUO(std::map<std::string,UniValue>& o, std::string strKey)
501 if (!o.count(strKey)) {
502 std::vector<unsigned char> emptyVec;
511 throw std::runtime_error(
"Amount is not a number or string");
514 throw std::runtime_error(
"Invalid amount");
516 throw std::runtime_error(
"Amount out of range");
525 if (!findSighashFlags(nHashType,
flagStr))
526 throw std::runtime_error(
"unknown sighash flag/sign option");
528 std::vector<CTransaction> txVariants;
529 txVariants.push_back(tx);
534 bool fComplete =
true;
538 if (!registers.count(
"privatekeys"))
539 throw std::runtime_error(
"privatekeys register variable must be set.");
541 UniValue keysObj = registers[
"privatekeys"];
543 for (
unsigned int kidx = 0; kidx < keysObj.
size(); kidx++) {
544 if (!keysObj[kidx].isStr())
545 throw std::runtime_error(
"privatekey not a std::string");
547 bool fGood = vchSecret.
SetString(keysObj[kidx].getValStr());
549 throw std::runtime_error(
"privatekey not valid");
556 if (!registers.count(
"prevtxs"))
557 throw std::runtime_error(
"prevtxs register variable must be set.");
558 UniValue prevtxsObj = registers[
"prevtxs"];
560 for (
unsigned int previdx = 0; previdx < prevtxsObj.
size(); previdx++) {
561 UniValue prevOut = prevtxsObj[previdx];
563 throw std::runtime_error(
"expected prevtxs internal object");
567 throw std::runtime_error(
"prevtxs internal object typecheck fail");
571 int nOut =
atoi(prevOut[
"vout"].getValStr());
573 throw std::runtime_error(
"vout must be positive");
575 std::vector<unsigned char> pkData(
ParseHexUV(prevOut[
"scriptPubKey"],
"scriptPubKey"));
576 CScript scriptPubKey(pkData.begin(), pkData.end());
580 if (coins->
IsAvailable(nOut) && coins->
vout[nOut].scriptPubKey != scriptPubKey) {
581 std::string err(
"Previous output scriptPubKey mismatch:\n");
584 throw std::runtime_error(err);
586 if ((
unsigned int)nOut >= coins->
vout.size())
587 coins->
vout.resize(nOut+1);
588 coins->
vout[nOut].scriptPubKey = scriptPubKey;
589 coins->
vout[nOut].nValue = 0;
590 if (prevOut.
exists(
"amount")) {
591 coins->
vout[nOut].nValue = AmountFromValue(prevOut[
"amount"]);
598 prevOut.
exists(
"redeemScript")) {
599 UniValue v = prevOut[
"redeemScript"];
600 std::vector<unsigned char> rsData(
ParseHexUV(v,
"redeemScript"));
601 CScript redeemScript(rsData.begin(), rsData.end());
607 const CKeyStore& keystore = tempKeystore;
612 for (
unsigned int i = 0; i < mergedTx.vin.size(); i++) {
613 CTxIn& txin = mergedTx.vin[i];
624 if (!fHashSingle || (i < mergedTx.vout.size()))
658 const std::string& commandVal)
660 std::unique_ptr<Secp256k1Init> ecc;
662 if (command ==
"nversion")
663 MutateTxVersion(tx, commandVal);
664 else if (command ==
"locktime")
665 MutateTxLocktime(tx, commandVal);
667 else if (command ==
"delin")
668 MutateTxDelInput(tx, commandVal);
669 else if (command ==
"in")
670 MutateTxAddInput(tx, commandVal);
672 else if (command ==
"delout")
673 MutateTxDelOutput(tx, commandVal);
674 else if (command ==
"outaddr")
675 MutateTxAddOutAddr(tx, commandVal);
676 else if (command ==
"outpubkey")
677 MutateTxAddOutPubKey(tx, commandVal);
678 else if (command ==
"outmultisig")
679 MutateTxAddOutMultiSig(tx, commandVal);
680 else if (command ==
"outscript")
681 MutateTxAddOutScript(tx, commandVal);
682 else if (command ==
"outdata")
683 MutateTxAddOutData(tx, commandVal);
685 else if (command ==
"sign") {
687 MutateTxSign(tx, commandVal);
690 else if (command ==
"load")
691 RegisterLoad(commandVal);
693 else if (command ==
"set")
694 RegisterSet(commandVal);
697 throw std::runtime_error(
"unknown command");
705 std::string jsonOutput = entry.write(4);
706 fprintf(stdout,
"%s\n", jsonOutput.c_str());
713 fprintf(stdout,
"%s\n", strHexHash.c_str());
720 fprintf(stdout,
"%s\n", strHex.c_str());
733 static std::string readStdin()
738 while (!feof(stdin)) {
739 size_t bread = fread(buf, 1,
sizeof(buf), stdin);
740 ret.append(buf, bread);
741 if (bread <
sizeof(buf))
746 throw std::runtime_error(
"error reading stdin");
748 boost::algorithm::trim_right(ret);
753 static int CommandLineRawTx(
int argc,
char* argv[])
755 std::string strPrint;
771 throw std::runtime_error(
"too few parameters");
774 std::string strHexTx(argv[1]);
776 strHexTx = readStdin();
779 throw std::runtime_error(
"invalid transaction encoding");
785 for (
int i = startArg; i < argc; i++) {
786 std::string arg = argv[i];
787 std::string key, value;
788 size_t eqpos = arg.find(
'=');
789 if (eqpos == std::string::npos)
792 key = arg.substr(0, eqpos);
793 value = arg.substr(eqpos + 1);
796 MutateTx(tx, key, value);
802 catch (
const boost::thread_interrupted&) {
805 catch (
const std::exception& e) {
806 strPrint = std::string(
"error: ") + e.what();
814 if (strPrint !=
"") {
815 fprintf((nRet == 0 ? stdout : stderr),
"%s\n", strPrint.c_str());
820 int main(
int argc,
char* argv[])
825 int ret = AppInitRawTx(argc, argv);
826 if (ret != CONTINUE_EXECUTION)
829 catch (
const std::exception& e) {
837 int ret = EXIT_FAILURE;
839 ret = CommandLineRawTx(argc, argv);
841 catch (
const std::exception& e) {
bool MoneyRange(const CAmount &nValue)
int64_t CAmount
Amount in satoshis (Can be negative)
int main(int argc, char *argv[])
uint256 ParseHashUO(std::map< std::string, UniValue > &o, std::string strKey)
std::vector< unsigned char > ParseHexUO(std::map< std::string, UniValue > &o, std::string strKey)
void SelectParams(const std::string &network)
Sets the params returned by Params() to those for the given BIP70 chain name.
std::string ChainNameFromCommandLine()
Looks for -regtest, -testnet and returns the appropriate BIP70 chain name.
void AppendParamsHelpMessages(std::string &strUsage, bool debugHelp)
Append the help messages for the chainparams options to the parameter string.
Basic key store, that keeps keys in an address->secret map.
virtual bool AddCScript(const CScript &redeemScript)
Support for BIP 0013 : see https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki.
base58-encoded Bitcoin addresses.
A base58-encoded secret key.
bool SetString(const char *pszSecret)
Pruned version of CTransaction: only retains metadata and unspent transaction outputs.
std::vector< CTxOut > vout
unspent transaction outputs; spent outputs are .IsNull(); spent outputs at the end of the array are d...
bool IsAvailable(unsigned int nPos) const
check whether a particular output is still available
A reference to a mutable cache entry.
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Abstract view on the open txout dataset.
An encapsulated private key.
A virtual base class for key stores.
virtual bool AddKey(const CKey &key)
An encapsulated public key.
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.
static const int32_t MAX_STANDARD_VERSION
const uint256 & GetHash() const
An input of a transaction.
CScriptWitness scriptWitness
An output of a transaction.
Users of this module must hold an ECCVerifyHandle.
ECCVerifyHandle globalVerifyHandle
bool checkObject(const std::map< std::string, UniValue::VType > &memberTypes)
const std::string & getValStr() const
bool read(const char *raw)
bool exists(const std::string &key) const
std::string GetHex() const
std::string FormatFullVersion()
CScript ParseScript(const std::string &s)
std::vector< unsigned char > ParseHexUV(const UniValue &v, const std::string &strName)
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 int serializeFlags=0)
bool DecodeHexTx(CMutableTransaction &tx, const std::string &strHexTx, bool fTryNoWitness=false)
uint256 ParseHashUV(const UniValue &v, const std::string &strName)
void TxToUniv(const CTransaction &tx, const uint256 &hashBlock, UniValue &entry)
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
void ECC_Start()
Initialize the elliptic curve support.
void ECC_Stop()
Deinitialize the elliptic curve support.
void UpdateTransaction(CMutableTransaction &tx, unsigned int nIn, const SignatureData &data)
SignatureData DataFromTransaction(const CMutableTransaction &tx, unsigned int nIn)
Extract signature data from a transaction, and insert it.
SignatureData CombineSignatures(const CScript &scriptPubKey, const BaseSignatureChecker &checker, const SignatureData &scriptSig1, const SignatureData &scriptSig2)
Combine two script signatures using a generic signature checker, intelligently, possibly with OP_0 pl...
bool ProduceSignature(const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
CScript GetScriptForWitness(const CScript &redeemscript)
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
CScript GetScriptForDestination(const CTxDestination &dest)
A mutable version of CTransaction.
std::vector< CTxOut > vout
uint256 uint256S(const char *str)
void ParseParameters(int argc, const char *const argv[])
bool GetBoolArg(const std::string &strArg, bool fDefault)
Return boolean argument or default value.
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
std::string HelpMessageGroup(const std::string &message)
Format a string to be used as group of options in help messages.
bool IsArgSet(const std::string &strArg)
Return true if the given argument has been manually set.
std::string HelpMessageOpt(const std::string &option, const std::string &message)
Format a string to be used as option description in help messages.
bool error(const char *fmt, const Args &... args)
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a boost::optional result.
bool IsSwitchChar(char c)
bool ParseMoney(const string &str, CAmount &nRet)
int64_t atoi64(const char *psz)
bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out)
Parse number as fixed point according to JSON number syntax.
bool IsHex(const string &str)
int atoi(const std::string &str)
vector< unsigned char > ParseHex(const char *psz)