Disallow using addresses in createmultisig

Make createmultisig only accept public keys with the old functionality
marked as deprecated.

Splits _createmultisig_redeemscript into two functions, one for
getting public keys from UniValue and one for getting addresses
from UniValue and then their respective public keys. The one for
retrieving address's public keys is located in rpcwallet.cpp

Changes addwitnessaddress's output to be a JSON object with
two fields, address and redeemscript.

Adds a test to deprecated_rpc.py for testing the deprecation.

Update the tests to use addwitnessaddress or give only public keys
to createmultisig. Anything that used addwitnessaddress was also
updated to reflect the new API.
This commit is contained in:
Andrew Chow
2017-09-29 00:21:28 -04:00
parent 0910cbe4ef
commit 1df206f854
15 changed files with 204 additions and 126 deletions

View File

@@ -18,6 +18,7 @@
#include <rpc/mining.h>
#include <rpc/safemode.h>
#include <rpc/server.h>
#include <rpc/util.h>
#include <script/sign.h>
#include <timedata.h>
#include <util.h>
@@ -1161,9 +1162,6 @@ UniValue sendmany(const JSONRPCRequest& request)
return wtx.GetHash().GetHex();
}
// Defined in rpc/misc.cpp
extern CScript _createmultisig_redeemScript(CWallet * const pwallet, const UniValue& params);
UniValue addmultisigaddress(const JSONRPCRequest& request)
{
CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
@@ -1181,16 +1179,22 @@ UniValue addmultisigaddress(const JSONRPCRequest& request)
"If 'account' is specified (DEPRECATED), assign address to that account.\n"
"\nArguments:\n"
"1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
"2. \"keys\" (string, required) A json array of bitcoin addresses or hex-encoded public keys\n"
"1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
"2. \"keys\" (string, required) A json array of bitcoin addresses or hex-encoded public keys\n"
" [\n"
" \"address\" (string) bitcoin address or hex-encoded public key\n"
" \"address\" (string) bitcoin address or hex-encoded public key\n"
" ...,\n"
" ]\n"
"3. \"account\" (string, optional) DEPRECATED. An account to assign the addresses to.\n"
"3. \"account\" (string, optional) DEPRECATED. An account to assign the addresses to.\n"
"\nResult:\n"
"\"address\" (string) A bitcoin address associated with the keys.\n"
"{\n"
" \"address\":\"multisigaddress\", (string) The value of the new multisig address.\n"
" \"redeemScript\":\"script\" (string) The string value of the hex-encoded redemption script.\n"
"}\n"
"\nResult (DEPRECATED. To see this result in v0.16 instead, please start bitcoind with -deprecatedrpc=addmultisigaddress).\n"
" clients should transition to the new output api before upgrading to v0.17.\n"
"\"address\" (string) A bitcoin address associated with the keys.\n"
"\nExamples:\n"
"\nAdd a multisig address from 2 addresses\n"
@@ -1207,14 +1211,34 @@ UniValue addmultisigaddress(const JSONRPCRequest& request)
if (!request.params[2].isNull())
strAccount = AccountFromValue(request.params[2]);
int required = request.params[0].get_int();
// Get the public keys
const UniValue& keys_or_addrs = request.params[1].get_array();
std::vector<CPubKey> pubkeys;
for (unsigned int i = 0; i < keys_or_addrs.size(); ++i) {
if (IsHex(keys_or_addrs[i].get_str()) && (keys_or_addrs[i].get_str().length() == 66 || keys_or_addrs[i].get_str().length() == 130)) {
pubkeys.push_back(HexToPubKey(keys_or_addrs[i].get_str()));
} else {
pubkeys.push_back(AddrToPubKey(pwallet, keys_or_addrs[i].get_str()));
}
}
// Construct using pay-to-script-hash:
CScript inner = _createmultisig_redeemScript(pwallet, request.params);
CScript inner = CreateMultisigRedeemscript(required, pubkeys);
pwallet->AddCScript(inner);
CTxDestination dest = pwallet->AddAndGetDestinationForScript(inner, g_address_type);
pwallet->SetAddressBook(dest, strAccount, "send");
return EncodeDestination(dest);
// Return old style interface
if (IsDeprecatedRPCEnabled("addmultisigaddress")) {
return EncodeDestination(dest);
}
UniValue result(UniValue::VOBJ);
result.pushKV("address", EncodeDestination(dest));
result.pushKV("redeemScript", HexStr(inner.begin(), inner.end()));
return result;
}
class Witnessifier : public boost::static_visitor<bool>