aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordexX7 <dexx@bitwatch.co>2015-03-22 19:07:28 +0100
committerdexX7 <dexx@bitwatch.co>2015-05-05 09:40:55 +0200
commit8ac2a4e1788426329b842eea7121b8eac7875c76 (patch)
treea98c0c25226c4a8191ffbf7760352c6d9a58bf1d
parentf0c4281f845e8f350acb01cd20ac7f4e085455b0 (diff)
RPC: show script verification errors in "signrawtransaction" result
If there are any script verification errors, when using "signrawtransaction", they are shown in the RPC result: ``` // ... Result: { "hex" : "value", (string) The hex-encoded raw transaction with signature(s) "complete" : true|false, (boolean) If the transaction has a complete set of signatures "errors" : [ (json array of objects) Script verification errors (if there are any) { "txid" : "hash", (string) The hash of the referenced, previous transaction "vout" : n, (numeric) The index of the output to spent and used as input "scriptSig" : "hex", (string) The hex-encoded signature script "sequence" : n, (numeric) Script sequence number "error" : "text" (string) Verification or signing error related to the input } ,... ] } ```
-rw-r--r--src/rpcrawtransaction.cpp45
1 files changed, 38 insertions, 7 deletions
diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp
index ca5aba8759..e84d2693a2 100644
--- a/src/rpcrawtransaction.cpp
+++ b/src/rpcrawtransaction.cpp
@@ -1,5 +1,5 @@
// Copyright (c) 2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Copyright (c) 2009-2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -13,6 +13,7 @@
#include "net.h"
#include "rpcserver.h"
#include "script/script.h"
+#include "script/script_error.h"
#include "script/sign.h"
#include "script/standard.h"
#include "uint256.h"
@@ -491,6 +492,18 @@ Value decodescript(const Array& params, bool fHelp)
return r;
}
+/** Pushes a JSON object for script verification or signing errors to vErrorsRet. */
+static void TxInErrorToJSON(const CTxIn& txin, Array& vErrorsRet, const std::string& strMessage)
+{
+ Object entry;
+ entry.push_back(Pair("txid", txin.prevout.hash.ToString()));
+ entry.push_back(Pair("vout", (uint64_t)txin.prevout.n));
+ entry.push_back(Pair("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
+ entry.push_back(Pair("sequence", (uint64_t)txin.nSequence));
+ entry.push_back(Pair("error", strMessage));
+ vErrorsRet.push_back(entry);
+}
+
Value signrawtransaction(const Array& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 4)
@@ -532,8 +545,18 @@ Value signrawtransaction(const Array& params, bool fHelp)
"\nResult:\n"
"{\n"
- " \"hex\": \"value\", (string) The raw transaction with signature(s) (hex-encoded string)\n"
- " \"complete\": true|false (boolean) if transaction has a complete set of signature\n"
+ " \"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n"
+ " \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n"
+ " \"errors\" : [ (json array of objects) Script verification errors (if there are any)\n"
+ " {\n"
+ " \"txid\" : \"hash\", (string) The hash of the referenced, previous transaction\n"
+ " \"vout\" : n, (numeric) The index of the output to spent and used as input\n"
+ " \"scriptSig\" : \"hex\", (string) The hex-encoded signature script\n"
+ " \"sequence\" : n, (numeric) Script sequence number\n"
+ " \"error\" : \"text\" (string) Verification or signing error related to the input\n"
+ " }\n"
+ " ,...\n"
+ " ]\n"
"}\n"
"\nExamples:\n"
@@ -568,7 +591,6 @@ Value signrawtransaction(const Array& params, bool fHelp)
// mergedTx will end up with all the signatures; it
// starts as a clone of the rawtx:
CMutableTransaction mergedTx(txVariants[0]);
- bool fComplete = true;
// Fetch previous transactions (inputs):
CCoinsView viewDummy;
@@ -683,12 +705,15 @@ Value signrawtransaction(const Array& params, bool fHelp)
bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
+ // Script verification errors
+ Array vErrors;
+
// Sign what we can:
for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
CTxIn& txin = mergedTx.vin[i];
const CCoins* coins = view.AccessCoins(txin.prevout.hash);
if (coins == NULL || !coins->IsAvailable(txin.prevout.n)) {
- fComplete = false;
+ TxInErrorToJSON(txin, vErrors, "Input not found or already spent");
continue;
}
const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey;
@@ -702,13 +727,19 @@ Value signrawtransaction(const Array& params, bool fHelp)
BOOST_FOREACH(const CMutableTransaction& 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)))
- fComplete = false;
+ ScriptError serror = SCRIPT_ERR_OK;
+ if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i), &serror)) {
+ TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror));
+ }
}
+ bool fComplete = vErrors.empty();
Object result;
result.push_back(Pair("hex", EncodeHexTx(mergedTx)));
result.push_back(Pair("complete", fComplete));
+ if (!vErrors.empty()) {
+ result.push_back(Pair("errors", vErrors));
+ }
return result;
}