5 #if defined(HAVE_CONFIG_H)    28 #include <boost/algorithm/string.hpp>    30 static bool fCreateBlank;
    31 static std::map<std::string,UniValue> registers;
    32 static const int CONTINUE_EXECUTION=-1;
    36 static void SetupBitcoinTxArgs()
    51     gArgs.
AddArg(
"outmultisig=VALUE:REQUIRED:PUBKEYS:PUBKEY1:PUBKEY2:....[:FLAGS]", 
"Add Pay To n-of-m Multi-sig output to TX. n = REQUIRED, m = PUBKEYS. "    52         "Optionally add the \"W\" flag to produce a pay-to-witness-script-hash output. "    54     gArgs.
AddArg(
"outpubkey=VALUE:PUBKEY[:FLAGS]", 
"Add pay-to-pubkey output to TX. "    55         "Optionally add the \"W\" flag to produce a pay-to-witness-pubkey-hash output. "    57     gArgs.
AddArg(
"outscript=VALUE:SCRIPT[:FLAGS]", 
"Add raw script output to TX. "    58         "Optionally add the \"W\" flag to produce a pay-to-witness-script-hash output. "    61     gArgs.
AddArg(
"sign=SIGHASH-FLAGS", 
"Add zero or more signatures to transaction. "    62         "This command requires JSON registers:"    63         "prevtxs=JSON object, "    64         "privatekeys=JSON object. "    79 static int AppInitRawTx(
int argc, 
char* argv[])
    87         fprintf(stderr, 
"Error parsing command line arguments: %s\n", 
error.c_str());
    94     } 
catch (
const std::exception& e) {
    95         fprintf(stderr, 
"Error: %s\n", e.what());
   104             "Usage:  bsha3-tx [options] <hex-tx> [commands]  Update hex-encoded bitcoin transaction\n" +
   105             "or:     bsha3-tx [options] -create [commands]   Create hex-encoded bitcoin transaction\n" +
   109         fprintf(stdout, 
"%s", strUsage.c_str());
   112             fprintf(stderr, 
"Error: too few parameters\n");
   117     return CONTINUE_EXECUTION;
   120 static void RegisterSetJson(
const std::string& key, 
const std::string& rawJson)
   123     if (!val.
read(rawJson)) {
   124         std::string strErr = 
"Cannot parse JSON for key " + key;
   125         throw std::runtime_error(strErr);
   128     registers[key] = val;
   131 static void RegisterSet(
const std::string& strInput)
   134     size_t pos = strInput.find(
':');
   135     if ((pos == std::string::npos) ||
   137         (pos == (strInput.size() - 1)))
   138         throw std::runtime_error(
"Register input requires NAME:VALUE");
   140     std::string key = strInput.substr(0, pos);
   141     std::string valStr = strInput.substr(pos + 1, std::string::npos);
   143     RegisterSetJson(key, valStr);
   146 static void RegisterLoad(
const std::string& strInput)
   149     size_t pos = strInput.find(
':');
   150     if ((pos == std::string::npos) ||
   152         (pos == (strInput.size() - 1)))
   153         throw std::runtime_error(
"Register load requires NAME:FILENAME");
   155     std::string key = strInput.substr(0, pos);
   156     std::string filename = strInput.substr(pos + 1, std::string::npos);
   158     FILE *f = 
fopen(filename.c_str(), 
"r");
   160         std::string strErr = 
"Cannot open file " + filename;
   161         throw std::runtime_error(strErr);
   166     while ((!feof(f)) && (!ferror(f))) {
   168         int bread = fread(buf, 1, 
sizeof(buf), f);
   172         valStr.insert(valStr.size(), buf, bread);
   175     int error = ferror(f);
   179         std::string strErr = 
"Error reading file " + filename;
   180         throw std::runtime_error(strErr);
   184     RegisterSetJson(key, valStr);
   187 static CAmount ExtractAndValidateValue(
const std::string& strValue)
   191         throw std::runtime_error(
"invalid TX output value");
   199         throw std::runtime_error(
"Invalid TX version requested: '" + cmdVal + 
"'");
   207     if (!
ParseInt64(cmdVal, &newLocktime) || newLocktime < 0LL || newLocktime > 0xffffffffLL)
   208         throw std::runtime_error(
"Invalid TX locktime requested: '" + cmdVal + 
"'");
   210     tx.
nLockTime = (
unsigned int) newLocktime;
   217     if (!
ParseInt64(strInIdx, &inIdx) || inIdx < 0 || inIdx >= static_cast<int64_t>(tx.
vin.size())) {
   218         throw std::runtime_error(
"Invalid TX input index '" + strInIdx + 
"'");
   224         if (strInIdx == 
"" || cnt == inIdx) {
   225             if (txin.
nSequence > MAX_BIP125_RBF_SEQUENCE) {
   226                 txin.
nSequence = MAX_BIP125_RBF_SEQUENCE;
   235     std::vector<std::string> vStrInputParts;
   236     boost::split(vStrInputParts, strInput, boost::is_any_of(
":"));
   239     if (vStrInputParts.size()<2)
   240         throw std::runtime_error(
"TX input missing separator");
   245         throw std::runtime_error(
"invalid TX input txid");
   248     static const unsigned int minTxOutSz = 9;
   249     static const unsigned int maxVout = MAX_BLOCK_WEIGHT / (WITNESS_SCALE_FACTOR * minTxOutSz);
   252     const std::string& strVout = vStrInputParts[1];
   254     if (!
ParseInt64(strVout, &vout) || vout < 0 || vout > 
static_cast<int64_t
>(maxVout))
   255         throw std::runtime_error(
"invalid TX input vout '" + strVout + 
"'");
   258     uint32_t nSequenceIn=std::numeric_limits<unsigned int>::max();
   259     if (vStrInputParts.size() > 2)
   260         nSequenceIn = std::stoul(vStrInputParts[2]);
   264     tx.
vin.push_back(txin);
   270     std::vector<std::string> vStrInputParts;
   271     boost::split(vStrInputParts, strInput, boost::is_any_of(
":"));
   273     if (vStrInputParts.size() != 2)
   274         throw std::runtime_error(
"TX output missing or too many separators");
   277     CAmount value = ExtractAndValidateValue(vStrInputParts[0]);
   280     std::string strAddr = vStrInputParts[1];
   283         throw std::runtime_error(
"invalid TX output address");
   288     CTxOut txout(value, scriptPubKey);
   289     tx.
vout.push_back(txout);
   295     std::vector<std::string> vStrInputParts;
   296     boost::split(vStrInputParts, strInput, boost::is_any_of(
":"));
   298     if (vStrInputParts.size() < 2 || vStrInputParts.size() > 3)
   299         throw std::runtime_error(
"TX output missing or too many separators");
   302     CAmount value = ExtractAndValidateValue(vStrInputParts[0]);
   306     if (!pubkey.IsFullyValid())
   307         throw std::runtime_error(
"invalid TX output pubkey");
   311     bool bSegWit = 
false;
   312     bool bScriptHash = 
false;
   313     if (vStrInputParts.size() == 3) {
   314         std::string 
flags = vStrInputParts[2];
   315         bSegWit = (
flags.find(
'W') != std::string::npos);
   316         bScriptHash = (
flags.find(
'S') != std::string::npos);
   320         if (!pubkey.IsCompressed()) {
   321             throw std::runtime_error(
"Uncompressed pubkeys are not useable for SegWit outputs");
   332     CTxOut txout(value, scriptPubKey);
   333     tx.
vout.push_back(txout);
   339     std::vector<std::string> vStrInputParts;
   340     boost::split(vStrInputParts, strInput, boost::is_any_of(
":"));
   343     if (vStrInputParts.size()<3)
   344         throw std::runtime_error(
"Not enough multisig parameters");
   347     CAmount value = ExtractAndValidateValue(vStrInputParts[0]);
   350     uint32_t required = stoul(vStrInputParts[1]);
   353     uint32_t numkeys = stoul(vStrInputParts[2]);
   356     if (vStrInputParts.size() < numkeys + 3)
   357         throw std::runtime_error(
"incorrect number of multisig pubkeys");
   359     if (required < 1 || required > MAX_PUBKEYS_PER_MULTISIG || numkeys < 1 || numkeys > MAX_PUBKEYS_PER_MULTISIG || numkeys < required)
   360         throw std::runtime_error(
"multisig parameter mismatch. Required " \
   361                             + std::to_string(required) + 
" of " + std::to_string(numkeys) + 
"signatures.");
   364     std::vector<CPubKey> pubkeys;
   365     for(
int pos = 1; pos <= int(numkeys); pos++) {
   367         if (!pubkey.IsFullyValid())
   368             throw std::runtime_error(
"invalid TX output pubkey");
   369         pubkeys.push_back(pubkey);
   373     bool bSegWit = 
false;
   374     bool bScriptHash = 
false;
   375     if (vStrInputParts.size() == numkeys + 4) {
   376         std::string 
flags = vStrInputParts.back();
   377         bSegWit = (
flags.find(
'W') != std::string::npos);
   378         bScriptHash = (
flags.find(
'S') != std::string::npos);
   380     else if (vStrInputParts.size() > numkeys + 4) {
   382         throw std::runtime_error(
"Too many parameters");
   388         for (
const CPubKey& pubkey : pubkeys) {
   389             if (!pubkey.IsCompressed()) {
   390                 throw std::runtime_error(
"Uncompressed pubkeys are not useable for SegWit outputs");
   397         if (scriptPubKey.
size() > MAX_SCRIPT_ELEMENT_SIZE) {
   399                         "redeemScript exceeds size limit: %d > %d", scriptPubKey.
size(), MAX_SCRIPT_ELEMENT_SIZE));
   406     CTxOut txout(value, scriptPubKey);
   407     tx.
vout.push_back(txout);
   415     size_t pos = strInput.find(
':');
   418         throw std::runtime_error(
"TX output value not specified");
   420     if (pos != std::string::npos) {
   422         value = ExtractAndValidateValue(strInput.substr(0, pos));
   426     std::string strData = strInput.substr(pos + 1, std::string::npos);
   429         throw std::runtime_error(
"invalid TX output data");
   431     std::vector<unsigned char> data = 
ParseHex(strData);
   434     tx.
vout.push_back(txout);
   440     std::vector<std::string> vStrInputParts;
   441     boost::split(vStrInputParts, strInput, boost::is_any_of(
":"));
   442     if (vStrInputParts.size() < 2)
   443         throw std::runtime_error(
"TX output missing separator");
   446     CAmount value = ExtractAndValidateValue(vStrInputParts[0]);
   449     std::string strScript = vStrInputParts[1];
   453     bool bSegWit = 
false;
   454     bool bScriptHash = 
false;
   455     if (vStrInputParts.size() == 3) {
   456         std::string 
flags = vStrInputParts.back();
   457         bSegWit = (
flags.find(
'W') != std::string::npos);
   458         bScriptHash = (
flags.find(
'S') != std::string::npos);
   461     if (scriptPubKey.
size() > MAX_SCRIPT_SIZE) {
   463                     "script exceeds size limit: %d > %d", scriptPubKey.
size(), MAX_SCRIPT_SIZE));
   470         if (scriptPubKey.
size() > MAX_SCRIPT_ELEMENT_SIZE) {
   472                         "redeemScript exceeds size limit: %d > %d", scriptPubKey.
size(), MAX_SCRIPT_ELEMENT_SIZE));
   478     CTxOut txout(value, scriptPubKey);
   479     tx.
vout.push_back(txout);
   486     if (!
ParseInt64(strInIdx, &inIdx) || inIdx < 0 || inIdx >= static_cast<int64_t>(tx.
vin.size())) {
   487         throw std::runtime_error(
"Invalid TX input index '" + strInIdx + 
"'");
   491     tx.
vin.erase(tx.
vin.begin() + inIdx);
   498     if (!
ParseInt64(strOutIdx, &outIdx) || outIdx < 0 || outIdx >= static_cast<int64_t>(tx.
vout.size())) {
   499         throw std::runtime_error(
"Invalid TX output index '" + strOutIdx + 
"'");
   503     tx.
vout.erase(tx.
vout.begin() + outIdx);
   506 static const unsigned int N_SIGHASH_OPTS = 6;
   507 static const struct {
   510 } sighashOptions[N_SIGHASH_OPTS] = {
   519 static bool findSighashFlags(
int& 
flags, 
const std::string& 
flagStr)
   523     for (
unsigned int i = 0; i < N_SIGHASH_OPTS; i++) {
   525             flags = sighashOptions[i].flags;
   536         throw std::runtime_error(
"Amount is not a number or string");
   539         throw std::runtime_error(
"Invalid amount");
   541         throw std::runtime_error(
"Amount out of range");
   550         if (!findSighashFlags(nHashType, 
flagStr))
   551             throw std::runtime_error(
"unknown sighash flag/sign option");
   560     if (!registers.count(
"privatekeys"))
   561         throw std::runtime_error(
"privatekeys register variable must be set.");
   563     UniValue keysObj = registers[
"privatekeys"];
   565     for (
unsigned int kidx = 0; kidx < keysObj.
size(); kidx++) {
   566         if (!keysObj[kidx].isStr())
   567             throw std::runtime_error(
"privatekey not a std::string");
   570             throw std::runtime_error(
"privatekey not valid");
   576     if (!registers.count(
"prevtxs"))
   577         throw std::runtime_error(
"prevtxs register variable must be set.");
   578     UniValue prevtxsObj = registers[
"prevtxs"];
   580         for (
unsigned int previdx = 0; previdx < prevtxsObj.
size(); previdx++) {
   581             UniValue prevOut = prevtxsObj[previdx];
   583                 throw std::runtime_error(
"expected prevtxs internal object");
   585             std::map<std::string, UniValue::VType> types = {
   591                 throw std::runtime_error(
"prevtxs internal object typecheck fail");
   595                 throw std::runtime_error(
"txid must be hexadecimal string (not '" + prevOut[
"txid"].get_str() + 
"')");
   598             const int nOut = prevOut[
"vout"].
get_int();
   600                 throw std::runtime_error(
"vout must be positive");
   603             std::vector<unsigned char> pkData(
ParseHexUV(prevOut[
"scriptPubKey"], 
"scriptPubKey"));
   604             CScript scriptPubKey(pkData.begin(), pkData.end());
   607                 const Coin& coin = view.AccessCoin(out);
   609                     std::string err(
"Previous output scriptPubKey mismatch:\n");
   612                     throw std::runtime_error(err);
   617                 if (prevOut.
exists(
"amount")) {
   618                     newcoin.
out.
nValue = AmountFromValue(prevOut[
"amount"]);
   621                 view.AddCoin(out, std::move(newcoin), 
true);
   627                 prevOut.
exists(
"redeemScript")) {
   628                 UniValue v = prevOut[
"redeemScript"];
   629                 std::vector<unsigned char> rsData(
ParseHexUV(v, 
"redeemScript"));
   630                 CScript redeemScript(rsData.begin(), rsData.end());
   636     const CKeyStore& keystore = tempKeystore;
   641     for (
unsigned int i = 0; i < mergedTx.vin.size(); i++) {
   642         CTxIn& txin = mergedTx.vin[i];
   652         if (!fHashSingle || (i < mergedTx.vout.size()))
   675                      const std::string& commandVal)
   677     std::unique_ptr<Secp256k1Init> ecc;
   679     if (command == 
"nversion")
   680         MutateTxVersion(tx, commandVal);
   681     else if (command == 
"locktime")
   682         MutateTxLocktime(tx, commandVal);
   683     else if (command == 
"replaceable") {
   684         MutateTxRBFOptIn(tx, commandVal);
   687     else if (command == 
"delin")
   688         MutateTxDelInput(tx, commandVal);
   689     else if (command == 
"in")
   690         MutateTxAddInput(tx, commandVal);
   692     else if (command == 
"delout")
   693         MutateTxDelOutput(tx, commandVal);
   694     else if (command == 
"outaddr")
   695         MutateTxAddOutAddr(tx, commandVal);
   696     else if (command == 
"outpubkey") {
   698         MutateTxAddOutPubKey(tx, commandVal);
   699     } 
else if (command == 
"outmultisig") {
   701         MutateTxAddOutMultiSig(tx, commandVal);
   702     } 
else if (command == 
"outscript")
   703         MutateTxAddOutScript(tx, commandVal);
   704     else if (command == 
"outdata")
   705         MutateTxAddOutData(tx, commandVal);
   707     else if (command == 
"sign") {
   709         MutateTxSign(tx, commandVal);
   712     else if (command == 
"load")
   713         RegisterLoad(commandVal);
   715     else if (command == 
"set")
   716         RegisterSet(commandVal);
   719         throw std::runtime_error(
"unknown command");
   727     std::string jsonOutput = entry.write(4);
   728     fprintf(stdout, 
"%s\n", jsonOutput.c_str());
   735     fprintf(stdout, 
"%s\n", strHexHash.c_str());
   742     fprintf(stdout, 
"%s\n", strHex.c_str());
   755 static std::string readStdin()
   760     while (!feof(stdin)) {
   761         size_t bread = fread(buf, 1, 
sizeof(buf), stdin);
   762         ret.append(buf, bread);
   763         if (bread < 
sizeof(buf))
   768         throw std::runtime_error(
"error reading stdin");
   770     boost::algorithm::trim_right(
ret);
   775 static int CommandLineRawTx(
int argc, 
char* argv[])
   777     std::string strPrint;
   793                 throw std::runtime_error(
"too few parameters");
   796             std::string strHexTx(argv[1]);
   798                 strHexTx = readStdin();
   801                 throw std::runtime_error(
"invalid transaction encoding");
   807         for (
int i = startArg; i < argc; i++) {
   808             std::string arg = argv[i];
   809             std::string key, value;
   810             size_t eqpos = arg.find(
'=');
   811             if (eqpos == std::string::npos)
   814                 key = arg.substr(0, eqpos);
   815                 value = arg.substr(eqpos + 1);
   818             MutateTx(tx, key, value);
   824     catch (
const boost::thread_interrupted&) {
   827     catch (
const std::exception& e) {
   828         strPrint = std::string(
"error: ") + e.what();
   836     if (strPrint != 
"") {
   837         fprintf((nRet == 0 ? stdout : stderr), 
"%s\n", strPrint.c_str());
   842 int main(
int argc, 
char* argv[])
   847         int ret = AppInitRawTx(argc, argv);
   848         if (
ret != CONTINUE_EXECUTION)
   851     catch (
const std::exception& e) {
   859     int ret = EXIT_FAILURE;
   861         ret = CommandLineRawTx(argc, argv);
   863     catch (
const std::exception& e) {
 std::vector< unsigned char > ParseHexUV(const UniValue &v, const std::string &strName)
bool HelpRequested(const ArgsManager &args)
void ECC_Start()
Initialize the elliptic curve support. 
static const int32_t MAX_STANDARD_VERSION
FILE * fopen(const fs::path &p, const char *mode)
bool read(const char *raw, size_t len)
bool IsPayToScriptHash() const
UniValue ret(UniValue::VARR)
bool MoneyRange(const CAmount &nValue)
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. 
bool AddCScript(const CScript &redeemScript) override
Support for BIP 0013 : see https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki. 
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
bool ParseParameters(int argc, const char *const argv[], std::string &error)
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value. 
A signature creator for transactions. 
const std::string & getValStr() const
const std::function< std::string(const char *)> G_TRANSLATION_FUN
Translate a message to the native language of the user. 
std::string GetHelpMessage() const
Get the help string. 
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 ...
bool ParseInt64(const std::string &str, int64_t *out)
Convert string to signed 64-bit integer with strict parse error feedback. 
Users of this module must hold an ECCVerifyHandle. 
std::string ScriptToAsmStr(const CScript &script, const bool fAttemptSighashDecode=false)
Create the assembly string representation of a CScript object. 
Abstract view on the open txout dataset. 
An input of a transaction. 
boost::variant< CNoDestination, CKeyID, CScriptID, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessUnknown > CTxDestination
A txout script template with a specific destination. 
void ECC_Stop()
Deinitialize the elliptic curve support. 
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. 
bool AddKey(const CKey &key)
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. 
bool IsHex(const std::string &str)
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. 
An outpoint - a combination of a transaction hash and an index n into its vout. 
std::vector< CTxOut > vout
std::string FormatFullVersion()
bool checkObject(const std::map< std::string, UniValue::VType > &memberTypes) const
CTxDestination DecodeDestination(const std::string &str)
void SetupChainParamsBaseOptions()
Set the arguments for chainparams. 
bool IsSwitchChar(char c)
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. 
void AddArg(const std::string &name, const std::string &help, const bool debug_only, const OptionsCategory &cat)
Add argument. 
A virtual base class for key stores. 
void UpdateInput(CTxIn &input, const SignatureData &data)
bool DecodeHexTx(CMutableTransaction &tx, const std::string &hex_tx, bool try_no_witness=false, bool try_witness=true)
std::string GetHex() const
std::string EncodeHexTx(const CTransaction &tx, const int serializeFlags=0)
bool ProduceSignature(const SigningProvider &provider, const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator. 
ECCVerifyHandle globalVerifyHandle
bool error(const char *fmt, const Args &... args)
A reference to a CScript: the Hash360 of its serialization (see script.h) 
A mutable version of CTransaction. 
std::string GetChainName() const
Looks for -regtest, -testnet and returns the appropriate BIP70 chain name. 
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 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. 
CScript ParseScript(const std::string &s)
CScript GetScriptForWitness(const CScript &redeemscript)
Generate a pay-to-witness script for the given redeem script. 
Basic key store, that keeps keys in an address->secret map. 
bool IsPayToWitnessScriptHash() const
bool IsValid() const
Check whether this private key is valid. 
std::vector< unsigned char > ParseHex(const char *psz)