Merge #11415: [RPC] Disallow using addresses in createmultisig

1df206f Disallow using addresses in createmultisig (Andrew Chow)

Pull request description:

  This PR should be the last part of #7965.

  This PR makes createmultisig only accept public keys and marks the old functionality of accepting addresses as deprecated.

  It also splits `_createmultisig_redeemscript` into two functions, `_createmultisig_getpubkeys` and `_createmultisig_getaddr_pubkeys`. `_createmultisig_getpubkeys` retrieves public keys from the RPC parameters and `_createmultisig_getaddr_pubkeys` retrieves addresses' public keys from the wallet. `_createmultisig_getaddr_pubkeys` requires the wallet and is only used by `addwitnessaddress` (except when `createmultisig` is used in deprecated mode).

  `addwitnessaddress`'s API is also changed. Instead of returning just an address, it now returns the same thing as `createmultisig`: a JSON object with two fields, address and redeemscript.

Tree-SHA512: a5796e41935ad5e47d8165ff996a8b20d5112b5fc1a06a6d3c7f5513c13e7628a4fd37ec30fde05d8b15abfed51bc250710140f6834b13f64d0a0e47a3817969
This commit is contained in:
Wladimir J. van der Laan
2018-01-24 13:34:30 +01:00
15 changed files with 204 additions and 126 deletions
+36 -12
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>