aboutsummaryrefslogtreecommitdiff
path: root/src/rpc/util.cpp
diff options
context:
space:
mode:
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;
+}