New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)

This commit is contained in:
Gavin Andresen 2012-07-17 12:06:13 -04:00
parent 18871d4785
commit 3c3666d67e

View file

@ -276,14 +276,16 @@ Value decoderawtransaction(const Array& params, bool fHelp)
Value signrawtransaction(const Array& params, bool fHelp) Value signrawtransaction(const Array& params, bool fHelp)
{ {
if (fHelp || params.size() < 1 || params.size() > 3) if (fHelp || params.size() < 1 || params.size() > 4)
throw runtime_error( throw runtime_error(
"signrawtransaction <hex string> [{\"txid\":txid,\"vout\":n,\"scriptPubKey\":hex},...] [<privatekey1>,...]\n" "signrawtransaction <hex string> [{\"txid\":txid,\"vout\":n,\"scriptPubKey\":hex},...] [<privatekey1>,...] [sighashtype=\"ALL\"]\n"
"Sign inputs for raw transaction (serialized, hex-encoded).\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 is an array of previous transaction outputs that\n"
"this transaction depends on but may not yet be in the blockchain.\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 is an array of base58-encoded private\n"
"keys that, if given, will be the only keys used to sign the transaction.\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"
"ALL|ANYONECANPAY, NONE|ANYONECANPAY, SINGLE|ANYONECANPAY.\n"
"Returns json object with keys:\n" "Returns json object with keys:\n"
" hex : raw transaction with signature(s) (hex-encoded string)\n" " hex : raw transaction with signature(s) (hex-encoded string)\n"
" complete : 1 if transaction has a complete set of signature (0 if not)" " complete : 1 if transaction has a complete set of signature (0 if not)"
@ -402,6 +404,25 @@ Value signrawtransaction(const Array& params, bool fHelp)
} }
const CKeyStore& keystore = (fGivenKeys ? tempKeystore : *pwalletMain); const CKeyStore& keystore = (fGivenKeys ? tempKeystore : *pwalletMain);
int nHashType = SIGHASH_ALL;
if (params.size() > 3)
{
static map<string, int> mapSigHashValues =
boost::assign::map_list_of
(string("ALL"), int(SIGHASH_ALL))
(string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY))
(string("NONE"), int(SIGHASH_NONE))
(string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY))
(string("SINGLE"), int(SIGHASH_SINGLE))
(string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY))
;
string strHashType = params[3].get_str();
if (mapSigHashValues.count(strHashType))
nHashType = mapSigHashValues[strHashType];
else
throw JSONRPCError(-8, "Invalid sighash param");
}
// Sign what we can: // Sign what we can:
for (unsigned int i = 0; i < mergedTx.vin.size(); i++) for (unsigned int i = 0; i < mergedTx.vin.size(); i++)
{ {
@ -414,7 +435,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
const CScript& prevPubKey = mapPrevOut[txin.prevout]; const CScript& prevPubKey = mapPrevOut[txin.prevout];
txin.scriptSig.clear(); txin.scriptSig.clear();
SignSignature(keystore, prevPubKey, mergedTx, i); SignSignature(keystore, prevPubKey, mergedTx, i, nHashType);
// ... and merge in other signatures: // ... and merge in other signatures:
BOOST_FOREACH(const CTransaction& txv, txVariants) BOOST_FOREACH(const CTransaction& txv, txVariants)