BSHA3  0.17.99
P2P Blockchain, based on Bitcoin
util.cpp
Go to the documentation of this file.
1 // Copyright (c) 2017-2018 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <key_io.h>
6 #include <keystore.h>
7 #include <rpc/protocol.h>
8 #include <rpc/util.h>
9 #include <tinyformat.h>
10 #include <utilstrencodings.h>
11 
12 // Converts a hex string to a public key if possible
13 CPubKey HexToPubKey(const std::string& hex_in)
14 {
15  if (!IsHex(hex_in)) {
16  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid public key: " + hex_in);
17  }
18  CPubKey vchPubKey(ParseHex(hex_in));
19  if (!vchPubKey.IsFullyValid()) {
20  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid public key: " + hex_in);
21  }
22  return vchPubKey;
23 }
24 
25 // Retrieves a public key for an address from the given CKeyStore
26 CPubKey AddrToPubKey(CKeyStore* const keystore, const std::string& addr_in)
27 {
28  CTxDestination dest = DecodeDestination(addr_in);
29  if (!IsValidDestination(dest)) {
30  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address: " + addr_in);
31  }
32  CKeyID key = GetKeyForDestination(*keystore, dest);
33  if (key.IsNull()) {
34  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("%s does not refer to a key", addr_in));
35  }
36  CPubKey vchPubKey;
37  if (!keystore->GetPubKey(key, vchPubKey)) {
38  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("no full public key for address %s", addr_in));
39  }
40  if (!vchPubKey.IsFullyValid()) {
41  throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet contains an invalid public key");
42  }
43  return vchPubKey;
44 }
45 
46 // Creates a multisig redeemscript from a given list of public keys and number required.
47 CScript CreateMultisigRedeemscript(const int required, const std::vector<CPubKey>& pubkeys)
48 {
49  // Gather public keys
50  if (required < 1) {
51  throw JSONRPCError(RPC_INVALID_PARAMETER, "a multisignature address must require at least one key to redeem");
52  }
53  if ((int)pubkeys.size() < required) {
54  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("not enough keys supplied (got %u keys, but need at least %d to redeem)", pubkeys.size(), required));
55  }
56  if (pubkeys.size() > 16) {
57  throw JSONRPCError(RPC_INVALID_PARAMETER, "Number of keys involved in the multisignature address creation > 16\nReduce the number");
58  }
59 
60  CScript result = GetScriptForMultisig(required, pubkeys);
61 
62  if (result.size() > MAX_SCRIPT_ELEMENT_SIZE) {
63  throw JSONRPCError(RPC_INVALID_PARAMETER, (strprintf("redeemScript exceeds size limit: %d > %d", result.size(), MAX_SCRIPT_ELEMENT_SIZE)));
64  }
65 
66  return result;
67 }
68 
69 class DescribeAddressVisitor : public boost::static_visitor<UniValue>
70 {
71 public:
72  explicit DescribeAddressVisitor() {}
73 
74  UniValue operator()(const CNoDestination& dest) const
75  {
76  return UniValue(UniValue::VOBJ);
77  }
78 
79  UniValue operator()(const CKeyID& keyID) const
80  {
82  obj.pushKV("isscript", false);
83  obj.pushKV("iswitness", false);
84  return obj;
85  }
86 
87  UniValue operator()(const CScriptID& scriptID) const
88  {
90  obj.pushKV("isscript", true);
91  obj.pushKV("iswitness", false);
92  return obj;
93  }
94 
96  {
98  obj.pushKV("isscript", false);
99  obj.pushKV("iswitness", true);
100  obj.pushKV("witness_version", 0);
101  obj.pushKV("witness_program", HexStr(id.begin(), id.end()));
102  return obj;
103  }
104 
106  {
108  obj.pushKV("isscript", true);
109  obj.pushKV("iswitness", true);
110  obj.pushKV("witness_version", 0);
111  obj.pushKV("witness_program", HexStr(id.begin(), id.end()));
112  return obj;
113  }
114 
116  {
118  obj.pushKV("iswitness", true);
119  obj.pushKV("witness_version", (int)id.version);
120  obj.pushKV("witness_program", HexStr(id.program, id.program + id.length));
121  return obj;
122  }
123 };
124 
126 {
127  return boost::apply_visitor(DescribeAddressVisitor(), dest);
128 }
CScript CreateMultisigRedeemscript(const int required, const std::vector< CPubKey > &pubkeys)
Definition: util.cpp:47
CPubKey AddrToPubKey(CKeyStore *const keystore, const std::string &addr_in)
Definition: util.cpp:26
#define strprintf
Definition: tinyformat.h:1066
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
Definition: standard.cpp:324
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
CPubKey HexToPubKey(const std::string &hex_in)
Definition: util.cpp:13
UniValue DescribeAddress(const CTxDestination &dest)
Definition: util.cpp:125
CKeyID GetKeyForDestination(const CKeyStore &store, const CTxDestination &dest)
Return the CKeyID of the key involved in a script (if there is a unique one).
Definition: keystore.cpp:177
UniValue operator()(const WitnessUnknown &id) const
Definition: util.cpp:115
UniValue operator()(const WitnessV0ScriptHash &id) const
Definition: util.cpp:105
bool IsNull() const
Definition: uint256.h:32
Invalid, missing or duplicate parameter.
Definition: protocol.h:52
UniValue operator()(const CNoDestination &dest) const
Definition: util.cpp:74
virtual bool GetPubKey(const CKeyID &address, CPubKey &pubkey) const
Definition: sign.h:35
bool IsFullyValid() const
fully validate whether this is a valid public key (more expensive than IsValid()) ...
Definition: pubkey.cpp:206
boost::variant< CNoDestination, CKeyID, CScriptID, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:123
CTxDestination subtype to encode any future Witness version.
Definition: standard.h:92
UniValue operator()(const CScriptID &scriptID) const
Definition: util.cpp:87
An encapsulated public key.
Definition: pubkey.h:30
bool IsHex(const std::string &str)
UniValue operator()(const WitnessV0KeyHash &id) const
Definition: util.cpp:95
auto end
Definition: rpcwallet.cpp:1068
bool pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:133
Invalid address or key.
Definition: protocol.h:50
UniValue operator()(const CKeyID &keyID) const
Definition: util.cpp:79
CTxDestination DecodeDestination(const std::string &str)
Definition: key_io.cpp:214
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:384
A virtual base class for key stores.
Definition: keystore.h:19
A reference to a CKey: the Hash360 of its serialized public key.
Definition: pubkey.h:20
A reference to a CScript: the Hash360 of its serialization (see script.h)
Definition: standard.h:22
size_type size() const
Definition: prevector.h:293
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
Definition: standard.cpp:301
UniValue JSONRPCError(int code, const std::string &message)
Definition: protocol.cpp:51
std::vector< unsigned char > ParseHex(const char *psz)