aboutsummaryrefslogtreecommitdiff
path: root/src/rpcrawtransaction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rpcrawtransaction.cpp')
-rw-r--r--src/rpcrawtransaction.cpp26
1 files changed, 15 insertions, 11 deletions
diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp
index 57cba15ecf..b037457140 100644
--- a/src/rpcrawtransaction.cpp
+++ b/src/rpcrawtransaction.cpp
@@ -280,21 +280,18 @@ Value signrawtransaction(const Array& params, bool fHelp)
throw runtime_error(
"signrawtransaction <hex string> [{\"txid\":txid,\"vout\":n,\"scriptPubKey\":hex},...] [<privatekey1>,...] [sighashtype=\"ALL\"]\n"
"Sign inputs for raw transaction (serialized, hex-encoded).\n"
- "Second optional argument is an array of previous transaction outputs that\n"
+ "Second optional argument (may be null) is an array of previous transaction outputs that\n"
"this transaction depends on but may not yet be in the blockchain.\n"
- "Third optional argument is an array of base58-encoded private\n"
+ "Third optional argument (may be null) is an array of base58-encoded private\n"
"keys that, if given, will be the only keys used to sign the transaction.\n"
- "Fourth option is a string that is one of six values; ALL, NONE, SINGLE or\n"
+ "Fourth optional argument is a string that is one of six values; ALL, NONE, SINGLE or\n"
"ALL|ANYONECANPAY, NONE|ANYONECANPAY, SINGLE|ANYONECANPAY.\n"
"Returns json object with keys:\n"
" hex : raw transaction with signature(s) (hex-encoded string)\n"
" complete : 1 if transaction has a complete set of signature (0 if not)"
+ HelpRequiringPassphrase());
- if (params.size() < 3)
- EnsureWalletIsUnlocked();
-
- RPCTypeCheck(params, list_of(str_type)(array_type)(array_type));
+ RPCTypeCheck(params, list_of(str_type)(array_type)(array_type)(str_type), true);
vector<unsigned char> txData(ParseHex(params[0].get_str()));
CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
@@ -343,7 +340,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
}
// Add previous txouts given in the RPC call:
- if (params.size() > 1)
+ if (params.size() > 1 && params[1].type() != null_type)
{
Array prevTxs = params[1].get_array();
BOOST_FOREACH(Value& p, prevTxs)
@@ -390,7 +387,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
bool fGivenKeys = false;
CBasicKeyStore tempKeystore;
- if (params.size() > 2)
+ if (params.size() > 2 && params[2].type() != null_type)
{
fGivenKeys = true;
Array keys = params[2].get_array();
@@ -407,10 +404,13 @@ Value signrawtransaction(const Array& params, bool fHelp)
tempKeystore.AddKey(key);
}
}
+ else
+ EnsureWalletIsUnlocked();
+
const CKeyStore& keystore = (fGivenKeys ? tempKeystore : *pwalletMain);
int nHashType = SIGHASH_ALL;
- if (params.size() > 3)
+ if (params.size() > 3 && params[3].type() != null_type)
{
static map<string, int> mapSigHashValues =
boost::assign::map_list_of
@@ -428,6 +428,8 @@ Value signrawtransaction(const Array& params, bool fHelp)
throw JSONRPCError(-8, "Invalid sighash param");
}
+ bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
+
// Sign what we can:
for (unsigned int i = 0; i < mergedTx.vin.size(); i++)
{
@@ -440,7 +442,9 @@ Value signrawtransaction(const Array& params, bool fHelp)
const CScript& prevPubKey = mapPrevOut[txin.prevout];
txin.scriptSig.clear();
- SignSignature(keystore, prevPubKey, mergedTx, i, nHashType);
+ // Only sign SIGHASH_SINGLE if there's a corresponding output:
+ if (!fHashSingle || (i < mergedTx.vout.size()))
+ SignSignature(keystore, prevPubKey, mergedTx, i, nHashType);
// ... and merge in other signatures:
BOOST_FOREACH(const CTransaction& txv, txVariants)