From 3c3666d67ea9036c612bb83d6c8496d011cccaac Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Tue, 17 Jul 2012 12:06:13 -0400 Subject: [PATCH] New feature for signrawtransaction: specify signature hash (ALL/NONE/etc) --- src/rpcrawtransaction.cpp | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 8ffe4844c..66e4d85f3 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -276,14 +276,16 @@ Value decoderawtransaction(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( - "signrawtransaction [{\"txid\":txid,\"vout\":n,\"scriptPubKey\":hex},...] [,...]\n" + "signrawtransaction [{\"txid\":txid,\"vout\":n,\"scriptPubKey\":hex},...] [,...] [sighashtype=\"ALL\"]\n" "Sign inputs for raw transaction (serialized, hex-encoded).\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" "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" + "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" " hex : raw transaction with signature(s) (hex-encoded string)\n" " 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); + int nHashType = SIGHASH_ALL; + if (params.size() > 3) + { + static map 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: 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]; txin.scriptSig.clear(); - SignSignature(keystore, prevPubKey, mergedTx, i); + SignSignature(keystore, prevPubKey, mergedTx, i, nHashType); // ... and merge in other signatures: BOOST_FOREACH(const CTransaction& txv, txVariants)