Merge pull request #1690 from gavinandresen/signrawtx_null
Allow signrawtransaction '...' null null 'hashtype'
This commit is contained in:
commit
4a4a0c1196
3 changed files with 28 additions and 22 deletions
|
@ -74,7 +74,8 @@ Object JSONRPCError(int code, const string& message)
|
|||
}
|
||||
|
||||
void RPCTypeCheck(const Array& params,
|
||||
const list<Value_type>& typesExpected)
|
||||
const list<Value_type>& typesExpected,
|
||||
bool fAllowNull)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
BOOST_FOREACH(Value_type t, typesExpected)
|
||||
|
@ -82,8 +83,8 @@ void RPCTypeCheck(const Array& params,
|
|||
if (params.size() <= i)
|
||||
break;
|
||||
|
||||
const Value& v = params[i];
|
||||
if (v.type() != t)
|
||||
const Value& v = params[i];
|
||||
if (!((v.type() == t) || (fAllowNull && (v.type() == null_type))))
|
||||
{
|
||||
string err = strprintf("Expected type %s, got %s",
|
||||
Value_type_name[t], Value_type_name[v.type()]);
|
||||
|
@ -94,14 +95,16 @@ void RPCTypeCheck(const Array& params,
|
|||
}
|
||||
|
||||
void RPCTypeCheck(const Object& o,
|
||||
const map<string, Value_type>& typesExpected)
|
||||
const map<string, Value_type>& typesExpected,
|
||||
bool fAllowNull)
|
||||
{
|
||||
BOOST_FOREACH(const PAIRTYPE(string, Value_type)& t, typesExpected)
|
||||
{
|
||||
const Value& v = find_value(o, t.first);
|
||||
if (v.type() == null_type)
|
||||
if (!fAllowNull && v.type() == null_type)
|
||||
throw JSONRPCError(-3, strprintf("Missing %s", t.first.c_str()));
|
||||
if (v.type() != t.second)
|
||||
|
||||
if (!((v.type() == t.second) || (fAllowNull && (v.type() == null_type))))
|
||||
{
|
||||
string err = strprintf("Expected type %s for %s, got %s",
|
||||
Value_type_name[t.second], t.first.c_str(), Value_type_name[v.type()]);
|
||||
|
@ -2694,8 +2697,10 @@ Object CallRPC(const string& strMethod, const Array& params)
|
|||
|
||||
|
||||
template<typename T>
|
||||
void ConvertTo(Value& value)
|
||||
void ConvertTo(Value& value, bool fAllowNull=false)
|
||||
{
|
||||
if (fAllowNull && value.type() == null_type)
|
||||
return;
|
||||
if (value.type() == str_type)
|
||||
{
|
||||
// reinterpret string as unquoted json value
|
||||
|
@ -2703,7 +2708,8 @@ void ConvertTo(Value& value)
|
|||
string strJSON = value.get_str();
|
||||
if (!read_string(strJSON, value2))
|
||||
throw runtime_error(string("Error parsing JSON:")+strJSON);
|
||||
value = value2.get_value<T>();
|
||||
ConvertTo<T>(value2, fAllowNull);
|
||||
value = value2;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2754,8 +2760,8 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
|
|||
if (strMethod == "getrawtransaction" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||
if (strMethod == "createrawtransaction" && n > 0) ConvertTo<Array>(params[0]);
|
||||
if (strMethod == "createrawtransaction" && n > 1) ConvertTo<Object>(params[1]);
|
||||
if (strMethod == "signrawtransaction" && n > 1) ConvertTo<Array>(params[1]);
|
||||
if (strMethod == "signrawtransaction" && n > 2) ConvertTo<Array>(params[2]);
|
||||
if (strMethod == "signrawtransaction" && n > 1) ConvertTo<Array>(params[1], true);
|
||||
if (strMethod == "signrawtransaction" && n > 2) ConvertTo<Array>(params[2], true);
|
||||
|
||||
return params;
|
||||
}
|
||||
|
|
|
@ -28,13 +28,13 @@ json_spirit::Array RPCConvertValues(const std::string &strMethod, const std::vec
|
|||
Use like: RPCTypeCheck(params, boost::assign::list_of(str_type)(int_type)(obj_type));
|
||||
*/
|
||||
void RPCTypeCheck(const json_spirit::Array& params,
|
||||
const std::list<json_spirit::Value_type>& typesExpected);
|
||||
const std::list<json_spirit::Value_type>& typesExpected, bool fAllowNull=false);
|
||||
/*
|
||||
Check for expected keys/value types in an Object.
|
||||
Use like: RPCTypeCheck(object, boost::assign::map_list_of("name", str_type)("value", int_type));
|
||||
*/
|
||||
void RPCTypeCheck(const json_spirit::Object& o,
|
||||
const std::map<std::string, json_spirit::Value_type>& typesExpected);
|
||||
const std::map<std::string, json_spirit::Value_type>& typesExpected, bool fAllowNull=false);
|
||||
|
||||
typedef json_spirit::Value(*rpcfn_type)(const json_spirit::Array& params, bool fHelp);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue