aboutsummaryrefslogtreecommitdiff
path: root/src/rpc/util.cpp
diff options
context:
space:
mode:
authorAndrew Chow <achow101-github@achow101.com>2017-09-29 00:21:28 -0400
committerAndrew Chow <achow101-github@achow101.com>2018-01-11 14:13:24 -0500
commit1df206f854d222230dcffd58e1b496567e570978 (patch)
treeae69bf08457642e4bd354461bbc391747605a1aa /src/rpc/util.cpp
parent0910cbe4ef31eb95fd76c7c2f820419fe64a3150 (diff)
downloadbitcoin-1df206f854d222230dcffd58e1b496567e570978.tar.xz
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.
Diffstat (limited to 'src/rpc/util.cpp')
-rw-r--r--src/rpc/util.cpp68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp
new file mode 100644
index 0000000000..09ded4e46e
--- /dev/null
+++ b/src/rpc/util.cpp
@@ -0,0 +1,68 @@
+// Copyright (c) 2017 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <base58.h>
+#include <keystore.h>
+#include <pubkey.h>
+#include <rpc/protocol.h>
+#include <rpc/util.h>
+#include <tinyformat.h>
+#include <utilstrencodings.h>
+
+// Converts a hex string to a public key if possible
+CPubKey HexToPubKey(const std::string& hex_in)
+{
+ if (!IsHex(hex_in)) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid public key: " + hex_in);
+ }
+ CPubKey vchPubKey(ParseHex(hex_in));
+ if (!vchPubKey.IsFullyValid()) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid public key: " + hex_in);
+ }
+ return vchPubKey;
+}
+
+// Retrieves a public key for an address from the given CKeyStore
+CPubKey AddrToPubKey(CKeyStore* const keystore, const std::string& addr_in)
+{
+ CTxDestination dest = DecodeDestination(addr_in);
+ if (!IsValidDestination(dest)) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address: " + addr_in);
+ }
+ CKeyID key = GetKeyForDestination(*keystore, dest);
+ if (key.IsNull()) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("%s does not refer to a key", addr_in));
+ }
+ CPubKey vchPubKey;
+ if (!keystore->GetPubKey(key, vchPubKey)) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("no full public key for address %s", addr_in));
+ }
+ if (!vchPubKey.IsFullyValid()) {
+ throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet contains an invalid public key");
+ }
+ return vchPubKey;
+}
+
+// Creates a multisig redeemscript from a given list of public keys and number required.
+CScript CreateMultisigRedeemscript(const int required, const std::vector<CPubKey>& pubkeys)
+{
+ // Gather public keys
+ if (required < 1) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "a multisignature address must require at least one key to redeem");
+ }
+ if ((int)pubkeys.size() < required) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("not enough keys supplied (got %u keys, but need at least %d to redeem)", pubkeys.size(), required));
+ }
+ if (pubkeys.size() > 16) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Number of keys involved in the multisignature address creation > 16\nReduce the number");
+ }
+
+ CScript result = GetScriptForMultisig(required, pubkeys);
+
+ if (result.size() > MAX_SCRIPT_ELEMENT_SIZE) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, (strprintf("redeemScript exceeds size limit: %d > %d", result.size(), MAX_SCRIPT_ELEMENT_SIZE)));
+ }
+
+ return result;
+}