]> Git Repo - VerusCoin.git/blobdiff - src/komodo-tx.cpp
Build fix
[VerusCoin.git] / src / komodo-tx.cpp
index bce749d7f8758265bf26250cbda8110c0e33a795..263f042a990c352f427f476db740f1c174645e22 100644 (file)
@@ -1,15 +1,17 @@
 // Copyright (c) 2009-2014 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or https://www.opensource.org/licenses/mit-license.php .
 
-#include "base58.h"
 #include "clientversion.h"
 #include "coins.h"
 #include "consensus/consensus.h"
+#include "consensus/upgrades.h"
 #include "core_io.h"
+#include "key_io.h"
 #include "keystore.h"
 #include "primitives/transaction.h"
 #include "script/script.h"
+#include "pbaas/pbaas.h"
 #include "script/sign.h"
 #include <univalue.h>
 #include "util.h"
@@ -31,15 +33,32 @@ using namespace std;
 
 #include "komodo_interest.h"
 
+struct CCcontract_info *CCinit(struct CCcontract_info *cp, uint8_t evalcode)
+{
+    return NULL;
+}
+
 uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight)
 {
     return(0);
 }
 
-static bool fCreateBlank;
-static map<string,UniValue> registers;
+CConnectedChains ConnectedChains;
+CCurrencyDefinition CConnectedChains::GetCachedCurrency(const uint160 &currencyID)
+{
+    return CCurrencyDefinition();
+}
 
-static bool AppInitRawTx(int argc, char* argv[])
+static bool fCreateBlank;
+static std::map<std::string,UniValue> registers;
+static const int CONTINUE_EXECUTION=-1;
+boost::optional<libzcash::SaplingPaymentAddress> defaultSaplingDest;
+
+//
+// This function returns either one of EXIT_ codes when it's expected to stop the process or
+// CONTINUE_EXECUTION when it's expected to continue further.
+//
+static int AppInitRawTx(int argc, char* argv[])
 {
     //
     // Parameters
@@ -78,12 +97,12 @@ static bool AppInitRawTx(int argc, char* argv[])
         strUsage = HelpMessageGroup(_("Commands:"));
         strUsage += HelpMessageOpt("delin=N", _("Delete input N from TX"));
         strUsage += HelpMessageOpt("delout=N", _("Delete output N from TX"));
-        strUsage += HelpMessageOpt("in=TXID:VOUT", _("Add input to TX"));
+        strUsage += HelpMessageOpt("in=TXID:VOUT(:SEQUENCE_NUMBER)", _("Add input to TX"));
         strUsage += HelpMessageOpt("locktime=N", _("Set TX lock time to N"));
         strUsage += HelpMessageOpt("nversion=N", _("Set TX version to N"));
         strUsage += HelpMessageOpt("outaddr=VALUE:ADDRESS", _("Add address-based output to TX"));
         strUsage += HelpMessageOpt("outscript=VALUE:SCRIPT", _("Add raw script output to TX"));
-        strUsage += HelpMessageOpt("sign=SIGHASH-FLAGS", _("Add zero or more signatures to transaction") + ". " +
+        strUsage += HelpMessageOpt("sign=HEIGHT:SIGHASH-FLAGS", _("Add zero or more signatures to transaction") + ". " +
             _("This command requires JSON registers:") +
             _("prevtxs=JSON object") + ", " +
             _("privatekeys=JSON object") + ". " +
@@ -95,57 +114,61 @@ static bool AppInitRawTx(int argc, char* argv[])
         strUsage += HelpMessageOpt("set=NAME:JSON-STRING", _("Set register NAME to given JSON-STRING"));
         fprintf(stdout, "%s", strUsage.c_str());
 
-        return false;
+        if (argc < 2) {
+            fprintf(stderr, "Error: too few parameters\n");
+            return EXIT_FAILURE;
+        }
+        return EXIT_SUCCESS;
     }
-    return true;
+    return CONTINUE_EXECUTION;
 }
 
-static void RegisterSetJson(const string& key, const string& rawJson)
+static void RegisterSetJson(const std::string& key, const std::string& rawJson)
 {
     UniValue val;
     if (!val.read(rawJson)) {
-        string strErr = "Cannot parse JSON for key " + key;
-        throw runtime_error(strErr);
+        std::string strErr = "Cannot parse JSON for key " + key;
+        throw std::runtime_error(strErr);
     }
 
     registers[key] = val;
 }
 
-static void RegisterSet(const string& strInput)
+static void RegisterSet(const std::string& strInput)
 {
     // separate NAME:VALUE in string
     size_t pos = strInput.find(':');
-    if ((pos == string::npos) ||
+    if ((pos == std::string::npos) ||
         (pos == 0) ||
         (pos == (strInput.size() - 1)))
-        throw runtime_error("Register input requires NAME:VALUE");
+        throw std::runtime_error("Register input requires NAME:VALUE");
 
-    string key = strInput.substr(0, pos);
-    string valStr = strInput.substr(pos + 1, string::npos);
+    std::string key = strInput.substr(0, pos);
+    std::string valStr = strInput.substr(pos + 1, std::string::npos);
 
     RegisterSetJson(key, valStr);
 }
 
-static void RegisterLoad(const string& strInput)
+static void RegisterLoad(const std::string& strInput)
 {
     // separate NAME:FILENAME in string
     size_t pos = strInput.find(':');
-    if ((pos == string::npos) ||
+    if ((pos == std::string::npos) ||
         (pos == 0) ||
         (pos == (strInput.size() - 1)))
-        throw runtime_error("Register load requires NAME:FILENAME");
+        throw std::runtime_error("Register load requires NAME:FILENAME");
 
-    string key = strInput.substr(0, pos);
-    string filename = strInput.substr(pos + 1, string::npos);
+    std::string key = strInput.substr(0, pos);
+    std::string filename = strInput.substr(pos + 1, std::string::npos);
 
     FILE *f = fopen(filename.c_str(), "r");
     if (!f) {
-        string strErr = "Cannot open file " + filename;
-        throw runtime_error(strErr);
+        std::string strErr = "Cannot open file " + filename;
+        throw std::runtime_error(strErr);
     }
 
     // load file chunks into one big buffer
-    string valStr;
+    std::string valStr;
     while ((!feof(f)) && (!ferror(f))) {
         char buf[4096];
         int bread = fread(buf, 1, sizeof(buf), f);
@@ -159,106 +182,119 @@ static void RegisterLoad(const string& strInput)
     fclose(f);
 
     if (error) {
-        string strErr = "Error reading file " + filename;
-        throw runtime_error(strErr);
+        std::string strErr = "Error reading file " + filename;
+        throw std::runtime_error(strErr);
     }
 
     // evaluate as JSON buffer register
     RegisterSetJson(key, valStr);
 }
 
-static void MutateTxVersion(CMutableTransaction& tx, const string& cmdVal)
+static void MutateTxVersion(CMutableTransaction& tx, const std::string& cmdVal)
 {
     int64_t newVersion = atoi64(cmdVal);
-    if (newVersion < CTransaction::MIN_CURRENT_VERSION || newVersion > CTransaction::MAX_CURRENT_VERSION)
-        throw runtime_error("Invalid TX version requested");
+    if (newVersion < CTransaction::SPROUT_MIN_CURRENT_VERSION || newVersion > CTransaction::SPROUT_MAX_CURRENT_VERSION)
+        throw std::runtime_error("Invalid TX version requested");
 
     tx.nVersion = (int) newVersion;
 }
 
-static void MutateTxLocktime(CMutableTransaction& tx, const string& cmdVal)
+static void MutateTxExpiry(CMutableTransaction& tx, const std::string& cmdVal)
+{
+    int64_t newExpiry = atoi64(cmdVal);
+    if (newExpiry <= 0 || newExpiry >= TX_EXPIRY_HEIGHT_THRESHOLD) {
+        throw std::runtime_error("Invalid TX expiry requested");
+    }
+    tx.nExpiryHeight = (int) newExpiry;
+}
+
+static void MutateTxLocktime(CMutableTransaction& tx, const std::string& cmdVal)
 {
     int64_t newLocktime = atoi64(cmdVal);
     if (newLocktime < 0LL || newLocktime > 0xffffffffLL)
-        throw runtime_error("Invalid TX locktime requested");
+        throw std::runtime_error("Invalid TX locktime requested");
 
     tx.nLockTime = (unsigned int) newLocktime;
 }
 
-static void MutateTxAddInput(CMutableTransaction& tx, const string& strInput)
+static void MutateTxAddInput(CMutableTransaction& tx, const std::string& strInput)
 {
+    std::vector<std::string> vStrInputParts;
+    boost::split(vStrInputParts, strInput, boost::is_any_of(":"));
+
     // separate TXID:VOUT in string
-    size_t pos = strInput.find(':');
-    if ((pos == string::npos) ||
-        (pos == 0) ||
-        (pos == (strInput.size() - 1)))
-        throw runtime_error("TX input missing separator");
+    if (vStrInputParts.size()<2)
+        throw std::runtime_error("TX input missing separator");
 
     // extract and validate TXID
-    string strTxid = strInput.substr(0, pos);
+    std::string strTxid = vStrInputParts[0];
     if ((strTxid.size() != 64) || !IsHex(strTxid))
-        throw runtime_error("invalid TX input txid");
+        throw std::runtime_error("invalid TX input txid");
     uint256 txid(uint256S(strTxid));
 
     static const unsigned int minTxOutSz = 9;
     static const unsigned int maxVout = MAX_BLOCK_SIZE / minTxOutSz;
 
     // extract and validate vout
-    string strVout = strInput.substr(pos + 1, string::npos);
+    std::string strVout = vStrInputParts[1];
     int vout = atoi(strVout);
     if ((vout < 0) || (vout > (int)maxVout))
-        throw runtime_error("invalid TX input vout");
+        throw std::runtime_error("invalid TX input vout");
+
+    // extract the optional sequence number
+    uint32_t nSequenceIn=std::numeric_limits<unsigned int>::max();
+    if (vStrInputParts.size() > 2)
+        nSequenceIn = atoi(vStrInputParts[2]);
 
     // append to transaction input list
-    CTxIn txin(txid, vout);
+    CTxIn txin(txid, vout, CScript(), nSequenceIn);
     tx.vin.push_back(txin);
 }
 
-static void MutateTxAddOutAddr(CMutableTransaction& tx, const string& strInput)
+static void MutateTxAddOutAddr(CMutableTransaction& tx, const std::string& strInput)
 {
     // separate VALUE:ADDRESS in string
     size_t pos = strInput.find(':');
-    if ((pos == string::npos) ||
+    if ((pos == std::string::npos) ||
         (pos == 0) ||
         (pos == (strInput.size() - 1)))
-        throw runtime_error("TX output missing separator");
+        throw std::runtime_error("TX output missing separator");
 
     // extract and validate VALUE
-    string strValue = strInput.substr(0, pos);
+    std::string strValue = strInput.substr(0, pos);
     CAmount value;
     if (!ParseMoney(strValue, value))
-        throw runtime_error("invalid TX output value");
+        throw std::runtime_error("invalid TX output value");
 
     // extract and validate ADDRESS
-    string strAddr = strInput.substr(pos + 1, string::npos);
-    CBitcoinAddress addr(strAddr);
-    if (!addr.IsValid())
-        throw runtime_error("invalid TX output address");
-
-    // build standard output script via GetScriptForDestination()
-    CScript scriptPubKey = GetScriptForDestination(addr.Get());
+    std::string strAddr = strInput.substr(pos + 1, std::string::npos);
+    CTxDestination destination = DecodeDestination(strAddr);
+    if (!IsValidDestination(destination)) {
+        throw std::runtime_error("invalid TX output address");
+    }
+    CScript scriptPubKey = GetScriptForDestination(destination);
 
     // construct TxOut, append to transaction output list
     CTxOut txout(value, scriptPubKey);
     tx.vout.push_back(txout);
 }
 
-static void MutateTxAddOutScript(CMutableTransaction& tx, const string& strInput)
+static void MutateTxAddOutScript(CMutableTransaction& tx, const std::string& strInput)
 {
     // separate VALUE:SCRIPT in string
     size_t pos = strInput.find(':');
-    if ((pos == string::npos) ||
+    if ((pos == std::string::npos) ||
         (pos == 0))
-        throw runtime_error("TX output missing separator");
+        throw std::runtime_error("TX output missing separator");
 
     // extract and validate VALUE
-    string strValue = strInput.substr(0, pos);
+    std::string strValue = strInput.substr(0, pos);
     CAmount value;
     if (!ParseMoney(strValue, value))
-        throw runtime_error("invalid TX output value");
+        throw std::runtime_error("invalid TX output value");
 
     // extract and validate script
-    string strScript = strInput.substr(pos + 1, string::npos);
+    std::string strScript = strInput.substr(pos + 1, std::string::npos);
     CScript scriptPubKey = ParseScript(strScript); // throws on err
 
     // construct TxOut, append to transaction output list
@@ -266,26 +302,26 @@ static void MutateTxAddOutScript(CMutableTransaction& tx, const string& strInput
     tx.vout.push_back(txout);
 }
 
-static void MutateTxDelInput(CMutableTransaction& tx, const string& strInIdx)
+static void MutateTxDelInput(CMutableTransaction& tx, const std::string& strInIdx)
 {
     // parse requested deletion index
     int inIdx = atoi(strInIdx);
     if (inIdx < 0 || inIdx >= (int)tx.vin.size()) {
-        string strErr = "Invalid TX input index '" + strInIdx + "'";
-        throw runtime_error(strErr.c_str());
+        std::string strErr = "Invalid TX input index '" + strInIdx + "'";
+        throw std::runtime_error(strErr.c_str());
     }
 
     // delete input from transaction
     tx.vin.erase(tx.vin.begin() + inIdx);
 }
 
-static void MutateTxDelOutput(CMutableTransaction& tx, const string& strOutIdx)
+static void MutateTxDelOutput(CMutableTransaction& tx, const std::string& strOutIdx)
 {
     // parse requested deletion index
     int outIdx = atoi(strOutIdx);
     if (outIdx < 0 || outIdx >= (int)tx.vout.size()) {
-        string strErr = "Invalid TX output index '" + strOutIdx + "'";
-        throw runtime_error(strErr.c_str());
+        std::string strErr = "Invalid TX output index '" + strOutIdx + "'";
+        throw std::runtime_error(strErr.c_str());
     }
 
     // delete output from transaction
@@ -305,7 +341,7 @@ static const struct {
     {"SINGLE|ANYONECANPAY", SIGHASH_SINGLE|SIGHASH_ANYONECANPAY},
 };
 
-static bool findSighashFlags(int& flags, const string& flagStr)
+static bool findSighashFlags(int& flags, const std::string& flagStr)
 {
     flags = 0;
 
@@ -319,32 +355,48 @@ static bool findSighashFlags(int& flags, const string& flagStr)
     return false;
 }
 
-uint256 ParseHashUO(map<string,UniValue>& o, string strKey)
+uint256 ParseHashUO(std::map<std::string,UniValue>& o, std::string strKey)
 {
     if (!o.count(strKey))
         return uint256();
     return ParseHashUV(o[strKey], strKey);
 }
 
-vector<unsigned char> ParseHexUO(map<string,UniValue>& o, string strKey)
+std::vector<unsigned char> ParseHexUO(std::map<std::string,UniValue>& o, std::string strKey)
 {
     if (!o.count(strKey)) {
-        vector<unsigned char> emptyVec;
+        std::vector<unsigned char> emptyVec;
         return emptyVec;
     }
     return ParseHexUV(o[strKey], strKey);
 }
 
-
-static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
+static void MutateTxSign(CMutableTransaction& tx, const std::string& strInput)
 {
-    int nHashType = SIGHASH_ALL;
+    // separate HEIGHT:SIGHASH-FLAGS in string
+    size_t pos = strInput.find(':');
+    if ((pos == 0) ||
+        (pos == (strInput.size() - 1)))
+        throw std::runtime_error("Invalid sighash flag separator");
 
+    // extract and validate HEIGHT
+    std::string strHeight = strInput.substr(0, pos);
+    int nHeight = atoi(strHeight);
+    if (nHeight <= 0) {
+        throw std::runtime_error("invalid height");
+    }
+
+    // extract and validate SIGHASH-FLAGS
+    int nHashType = SIGHASH_ALL;
+    std::string flagStr;
+    if (pos != std::string::npos) {
+        flagStr = strInput.substr(pos + 1, std::string::npos);
+    }
     if (flagStr.size() > 0)
         if (!findSighashFlags(nHashType, flagStr))
-            throw runtime_error("unknown sighash flag/sign option");
+            throw std::runtime_error("unknown sighash flag/sign option");
 
-    vector<CTransaction> txVariants;
+    std::vector<CTransaction> txVariants;
     txVariants.push_back(tx);
 
     // mergedTx will end up with all the signatures; it
@@ -355,7 +407,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
     CCoinsViewCache view(&viewDummy);
 
     if (!registers.count("privatekeys"))
-        throw runtime_error("privatekeys register variable must be set.");
+        throw std::runtime_error("privatekeys register variable must be set.");
     bool fGivenKeys = false;
     CBasicKeyStore tempKeystore;
     UniValue keysObj = registers["privatekeys"];
@@ -363,51 +415,52 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
 
     for (size_t kidx = 0; kidx < keysObj.size(); kidx++) {
         if (!keysObj[kidx].isStr())
-            throw runtime_error("privatekey not a string");
-        CBitcoinSecret vchSecret;
-        bool fGood = vchSecret.SetString(keysObj[kidx].getValStr());
-        if (!fGood)
-            throw runtime_error("privatekey not valid");
-
-        CKey key = vchSecret.GetKey();
+            throw std::runtime_error("privatekey not a std::string");
+        CKey key = DecodeSecret(keysObj[kidx].getValStr());
+        if (!key.IsValid()) {
+            throw std::runtime_error("privatekey not valid");
+        }
         tempKeystore.AddKey(key);
     }
 
     // Add previous txouts given in the RPC call:
     if (!registers.count("prevtxs"))
-        throw runtime_error("prevtxs register variable must be set.");
+        throw std::runtime_error("prevtxs register variable must be set.");
     UniValue prevtxsObj = registers["prevtxs"];
     {
         for (size_t previdx = 0; previdx < prevtxsObj.size(); previdx++) {
             UniValue prevOut = prevtxsObj[previdx];
             if (!prevOut.isObject())
-                throw runtime_error("expected prevtxs internal object");
+                throw std::runtime_error("expected prevtxs internal object");
 
-            map<string,UniValue::VType> types = boost::assign::map_list_of("txid", UniValue::VSTR)("vout",UniValue::VNUM)("scriptPubKey",UniValue::VSTR);
+            std::map<std::string,UniValue::VType> types = boost::assign::map_list_of("txid", UniValue::VSTR)("vout",UniValue::VNUM)("scriptPubKey",UniValue::VSTR);
             if (!prevOut.checkObject(types))
-                throw runtime_error("prevtxs internal object typecheck fail");
+                throw std::runtime_error("prevtxs internal object typecheck fail");
 
             uint256 txid = ParseHashUV(prevOut["txid"], "txid");
 
             int nOut = atoi(prevOut["vout"].getValStr());
             if (nOut < 0)
-                throw runtime_error("vout must be positive");
+                throw std::runtime_error("vout must be positive");
 
-            vector<unsigned char> pkData(ParseHexUV(prevOut["scriptPubKey"], "scriptPubKey"));
+            std::vector<unsigned char> pkData(ParseHexUV(prevOut["scriptPubKey"], "scriptPubKey"));
             CScript scriptPubKey(pkData.begin(), pkData.end());
 
             {
                 CCoinsModifier coins = view.ModifyCoins(txid);
                 if (coins->IsAvailable(nOut) && coins->vout[nOut].scriptPubKey != scriptPubKey) {
-                    string err("Previous output scriptPubKey mismatch:\n");
-                    err = err + coins->vout[nOut].scriptPubKey.ToString() + "\nvs:\n"+
-                        scriptPubKey.ToString();
-                    throw runtime_error(err);
+                    std::string err("Previous output scriptPubKey mismatch:\n");
+                    err = err + ScriptToAsmStr(coins->vout[nOut].scriptPubKey) + "\nvs:\n"+
+                        ScriptToAsmStr(scriptPubKey);
+                    throw std::runtime_error(err);
                 }
                 if ((unsigned int)nOut >= coins->vout.size())
                     coins->vout.resize(nOut+1);
                 coins->vout[nOut].scriptPubKey = scriptPubKey;
-                coins->vout[nOut].nValue = 0; // we don't know the actual output value
+                coins->vout[nOut].nValue = 0;
+                if (prevOut.exists("amount")) {
+                    coins->vout[nOut].nValue = AmountFromValue(prevOut["amount"]);
+                }
             }
 
             // if redeemScript given and private keys given,
@@ -415,7 +468,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
             if (fGivenKeys && scriptPubKey.IsPayToScriptHash() &&
                 prevOut.exists("redeemScript")) {
                 UniValue v = prevOut["redeemScript"];
-                vector<unsigned char> rsData(ParseHexUV(v, "redeemScript"));
+                std::vector<unsigned char> rsData(ParseHexUV(v, "redeemScript"));
                 CScript redeemScript(rsData.begin(), rsData.end());
                 tempKeystore.AddCScript(redeemScript);
             }
@@ -426,6 +479,9 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
 
     bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
 
+    // Grab the consensus branch ID for the given height
+    auto consensusBranchId = CurrentEpochBranchId(nHeight, Params().GetConsensus());
+
     // Sign what we can:
     for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
         CTxIn& txin = mergedTx.vin[i];
@@ -435,17 +491,19 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
             continue;
         }
         const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey;
+        const CAmount& amount = coins->vout[txin.prevout.n].nValue;
 
-        txin.scriptSig.clear();
+        SignatureData sigdata;
         // Only sign SIGHASH_SINGLE if there's a corresponding output:
         if (!fHashSingle || (i < mergedTx.vout.size()))
-            SignSignature(keystore, prevPubKey, mergedTx, i, nHashType);
+            ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mergedTx, i, amount, prevPubKey, nHeight, nHashType), prevPubKey, sigdata, consensusBranchId);
 
         // ... and merge in other signatures:
-        BOOST_FOREACH(const CTransaction& txv, txVariants) {
-            txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig);
-        }
-        if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i)))
+        BOOST_FOREACH(const CTransaction& txv, txVariants)
+            sigdata = CombineSignatures(prevPubKey, MutableTransactionSignatureChecker(&mergedTx, i, amount), sigdata, DataFromTransaction(txv, i), consensusBranchId);
+        UpdateTransaction(mergedTx, i, sigdata);
+
+        if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i, amount), consensusBranchId))
             fComplete = false;
     }
 
@@ -459,13 +517,19 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
 
 class Secp256k1Init
 {
+    ECCVerifyHandle globalVerifyHandle;
+
 public:
-    Secp256k1Init() { ECC_Start(); }
-    ~Secp256k1Init() { ECC_Stop(); }
+    Secp256k1Init() {
+        ECC_Start();
+    }
+    ~Secp256k1Init() {
+        ECC_Stop();
+    }
 };
 
-static void MutateTx(CMutableTransaction& tx, const string& command,
-                     const string& commandVal)
+static void MutateTx(CMutableTransaction& tx, const std::string& command,
+                     const std::string& commandVal)
 {
     boost::scoped_ptr<Secp256k1Init> ecc;
 
@@ -473,6 +537,8 @@ static void MutateTx(CMutableTransaction& tx, const string& command,
         MutateTxVersion(tx, commandVal);
     else if (command == "locktime")
         MutateTxLocktime(tx, commandVal);
+    else if (command == "expiry")
+        MutateTxExpiry(tx, commandVal);
 
     else if (command == "delin")
         MutateTxDelInput(tx, commandVal);
@@ -498,7 +564,7 @@ static void MutateTx(CMutableTransaction& tx, const string& command,
         RegisterSet(commandVal);
 
     else
-        throw runtime_error("unknown command");
+        throw std::runtime_error("unknown command");
 }
 
 static void OutputTxJSON(const CTransaction& tx)
@@ -506,20 +572,20 @@ static void OutputTxJSON(const CTransaction& tx)
     UniValue entry(UniValue::VOBJ);
     TxToUniv(tx, uint256(), entry);
 
-    string jsonOutput = entry.write(4);
+    std::string jsonOutput = entry.write(4);
     fprintf(stdout, "%s\n", jsonOutput.c_str());
 }
 
 static void OutputTxHash(const CTransaction& tx)
 {
-    string strHexHash = tx.GetHash().GetHex(); // the hex-encoded transaction hash (aka the transaction id)
+    std::string strHexHash = tx.GetHash().GetHex(); // the hex-encoded transaction hash (aka the transaction id)
 
     fprintf(stdout, "%s\n", strHexHash.c_str());
 }
 
 static void OutputTxHex(const CTransaction& tx)
 {
-    string strHex = EncodeHexTx(tx);
+    std::string strHex = EncodeHexTx(tx);
 
     fprintf(stdout, "%s\n", strHex.c_str());
 }
@@ -534,10 +600,10 @@ static void OutputTx(const CTransaction& tx)
         OutputTxHex(tx);
 }
 
-static string readStdin()
+static std::string readStdin()
 {
     char buf[4096];
-    string ret;
+    std::string ret;
 
     while (!feof(stdin)) {
         size_t bread = fread(buf, 1, sizeof(buf), stdin);
@@ -547,7 +613,7 @@ static string readStdin()
     }
 
     if (ferror(stdin))
-        throw runtime_error("error reading stdin");
+        throw std::runtime_error("error reading stdin");
 
     boost::algorithm::trim_right(ret);
 
@@ -556,7 +622,7 @@ static string readStdin()
 
 static int CommandLineRawTx(int argc, char* argv[])
 {
-    string strPrint;
+    std::string strPrint;
     int nRet = 0;
     try {
         // Skip switches; Permit common stdin convention "-"
@@ -572,15 +638,15 @@ static int CommandLineRawTx(int argc, char* argv[])
         if (!fCreateBlank) {
             // require at least one param
             if (argc < 2)
-                throw runtime_error("too few parameters");
+                throw std::runtime_error("too few parameters");
 
             // param: hex-encoded bitcoin transaction
-            string strHexTx(argv[1]);
+            std::string strHexTx(argv[1]);
             if (strHexTx == "-")                 // "-" implies standard input
                 strHexTx = readStdin();
 
             if (!DecodeHexTx(txDecodeTmp, strHexTx))
-                throw runtime_error("invalid transaction encoding");
+                throw std::runtime_error("invalid transaction encoding");
 
             startArg = 2;
         } else
@@ -589,10 +655,10 @@ static int CommandLineRawTx(int argc, char* argv[])
         CMutableTransaction tx(txDecodeTmp);
 
         for (int i = startArg; i < argc; i++) {
-            string arg = argv[i];
-            string key, value;
+            std::string arg = argv[i];
+            std::string key, value;
             size_t eqpos = arg.find('=');
-            if (eqpos == string::npos)
+            if (eqpos == std::string::npos)
                 key = arg;
             else {
                 key = arg.substr(0, eqpos);
@@ -609,7 +675,7 @@ static int CommandLineRawTx(int argc, char* argv[])
         throw;
     }
     catch (const std::exception& e) {
-        strPrint = string("error: ") + e.what();
+        strPrint = std::string("error: ") + e.what();
         nRet = EXIT_FAILURE;
     }
     catch (...) {
@@ -628,8 +694,9 @@ int main(int argc, char* argv[])
     SetupEnvironment();
 
     try {
-        if(!AppInitRawTx(argc, argv))
-            return EXIT_FAILURE;
+        int ret = AppInitRawTx(argc, argv);
+        if (ret != CONTINUE_EXECUTION)
+            return ret;
     }
     catch (const std::exception& e) {
         PrintExceptionContinue(&e, "AppInitRawTx()");
This page took 0.049073 seconds and 4 git commands to generate.