mirror of
https://github.com/kvazar-network/kevacoin.git
synced 2025-01-24 13:54:16 +00:00
Add redeemScript to listunspent output and signrawtransaction input
signrawtransaction was unable to sign pay-to-script-hash inputs when given the list of private keys to use. With this commit you can provide the p2sh redemption script in the list of inputs.
This commit is contained in:
parent
2d43f88e1f
commit
03346a61b1
@ -226,6 +226,17 @@ Value listunspent(const Array& params, bool fHelp)
|
||||
entry.push_back(Pair("txid", out.tx->GetHash().GetHex()));
|
||||
entry.push_back(Pair("vout", out.i));
|
||||
entry.push_back(Pair("scriptPubKey", HexStr(pk.begin(), pk.end())));
|
||||
if (pk.IsPayToScriptHash())
|
||||
{
|
||||
CTxDestination address;
|
||||
if (ExtractDestination(pk, address))
|
||||
{
|
||||
const CScriptID& hash = boost::get<const CScriptID&>(address);
|
||||
CScript redeemScript;
|
||||
if (pwalletMain->GetCScript(hash, redeemScript))
|
||||
entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end())));
|
||||
}
|
||||
}
|
||||
entry.push_back(Pair("amount",ValueFromAmount(nValue)));
|
||||
entry.push_back(Pair("confirmations",out.nDepth));
|
||||
results.push_back(entry);
|
||||
@ -321,7 +332,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() < 1 || params.size() > 4)
|
||||
throw runtime_error(
|
||||
"signrawtransaction <hex string> [{\"txid\":txid,\"vout\":n,\"scriptPubKey\":hex},...] [<privatekey1>,...] [sighashtype=\"ALL\"]\n"
|
||||
"signrawtransaction <hex string> [{\"txid\":txid,\"vout\":n,\"scriptPubKey\":hex,\"redeemScript\":hex},...] [<privatekey1>,...] [sighashtype=\"ALL\"]\n"
|
||||
"Sign inputs for raw transaction (serialized, hex-encoded).\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 block chain.\n"
|
||||
@ -377,6 +388,28 @@ Value signrawtransaction(const Array& params, bool fHelp)
|
||||
view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
|
||||
}
|
||||
|
||||
bool fGivenKeys = false;
|
||||
CBasicKeyStore tempKeystore;
|
||||
if (params.size() > 2 && params[2].type() != null_type)
|
||||
{
|
||||
fGivenKeys = true;
|
||||
Array keys = params[2].get_array();
|
||||
BOOST_FOREACH(Value k, keys)
|
||||
{
|
||||
CBitcoinSecret vchSecret;
|
||||
bool fGood = vchSecret.SetString(k.get_str());
|
||||
if (!fGood)
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
|
||||
CKey key;
|
||||
bool fCompressed;
|
||||
CSecret secret = vchSecret.GetSecret(fCompressed);
|
||||
key.SetSecret(secret, fCompressed);
|
||||
tempKeystore.AddKey(key);
|
||||
}
|
||||
}
|
||||
else
|
||||
EnsureWalletIsUnlocked();
|
||||
|
||||
// Add previous txouts given in the RPC call:
|
||||
if (params.size() > 1 && params[1].type() != null_type)
|
||||
{
|
||||
@ -388,7 +421,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
|
||||
|
||||
Object prevOut = p.get_obj();
|
||||
|
||||
RPCTypeCheck(prevOut, map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type));
|
||||
RPCTypeCheck(prevOut, map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)("redeemScript",str_type));
|
||||
|
||||
uint256 txid = ParseHashO(prevOut, "txid");
|
||||
|
||||
@ -409,33 +442,23 @@ Value signrawtransaction(const Array& params, bool fHelp)
|
||||
}
|
||||
// what todo if txid is known, but the actual output isn't?
|
||||
}
|
||||
if ((unsigned int)nOut >= coins.vout.size())
|
||||
coins.vout.resize(nOut+1);
|
||||
coins.vout[nOut].scriptPubKey = scriptPubKey;
|
||||
coins.vout[nOut].nValue = 0; // we don't know the actual output value
|
||||
view.SetCoins(txid, coins);
|
||||
}
|
||||
}
|
||||
|
||||
bool fGivenKeys = false;
|
||||
CBasicKeyStore tempKeystore;
|
||||
if (params.size() > 2 && params[2].type() != null_type)
|
||||
{
|
||||
fGivenKeys = true;
|
||||
Array keys = params[2].get_array();
|
||||
BOOST_FOREACH(Value k, keys)
|
||||
{
|
||||
CBitcoinSecret vchSecret;
|
||||
bool fGood = vchSecret.SetString(k.get_str());
|
||||
if (!fGood)
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,"Invalid private key");
|
||||
CKey key;
|
||||
bool fCompressed;
|
||||
CSecret secret = vchSecret.GetSecret(fCompressed);
|
||||
key.SetSecret(secret, fCompressed);
|
||||
tempKeystore.AddKey(key);
|
||||
// if redeemScript given and not using the local wallet (private keys
|
||||
// given), add redeemScript to the tempKeystore so it can be signed:
|
||||
Value v = find_value(prevOut, "redeemScript");
|
||||
if (fGivenKeys && scriptPubKey.IsPayToScriptHash() && !(v == Value::null))
|
||||
{
|
||||
vector<unsigned char> rsData(ParseHexV(v, "redeemScript"));
|
||||
CScript redeemScript(rsData.begin(), rsData.end());
|
||||
tempKeystore.AddCScript(redeemScript);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
EnsureWalletIsUnlocked();
|
||||
|
||||
const CKeyStore& keystore = (fGivenKeys ? tempKeystore : *pwalletMain);
|
||||
|
||||
|
@ -127,4 +127,24 @@ BOOST_AUTO_TEST_CASE(rpc_rawparams)
|
||||
BOOST_CHECK_THROW(CallRPC("sendrawtransaction DEADBEEF"), runtime_error);
|
||||
BOOST_CHECK_THROW(CallRPC(string("sendrawtransaction ")+rawtx+" extra"), runtime_error);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(rpc_rawsign)
|
||||
{
|
||||
Value r;
|
||||
// input is a 1-of-2 multisig (so is output):
|
||||
string prevout =
|
||||
"[{\"txid\":\"b4cc287e58f87cdae59417329f710f3ecd75a4ee1d2872b7248f50977c8493f3\","
|
||||
"\"vout\":1,\"scriptPubKey\":\"a914b10c9df5f7edf436c697f02f1efdba4cf399615187\","
|
||||
"\"redeemScript\":\"512103debedc17b3df2badbcdd86d5feb4562b86fe182e5998abd8bcd4f122c6155b1b21027e940bb73ab8732bfdf7f9216ecefca5b94d6df834e77e108f68e66f126044c052ae\"}]";
|
||||
r = CallRPC(string("createrawtransaction ")+prevout+" "+
|
||||
"{\"3HqAe9LtNBjnsfM4CyYaWTnvCaUYT7v4oZ\":11}");
|
||||
string notsigned = r.get_str();
|
||||
string privkey1 = "\"KzsXybp9jX64P5ekX1KUxRQ79Jht9uzW7LorgwE65i5rWACL6LQe\"";
|
||||
string privkey2 = "\"Kyhdf5LuKTRx4ge69ybABsiUAWjVRK4XGxAKk2FQLp2HjGMy87Z4\"";
|
||||
r = CallRPC(string("signrawtransaction ")+notsigned+" "+prevout+" "+"[]");
|
||||
BOOST_CHECK(find_value(r.get_obj(), "complete").get_bool() == false);
|
||||
r = CallRPC(string("signrawtransaction ")+notsigned+" "+prevout+" "+"["+privkey1+","+privkey2+"]");
|
||||
BOOST_CHECK(find_value(r.get_obj(), "complete").get_bool() == true);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
Loading…
x
Reference in New Issue
Block a user