Bitcoin Core  0.19.99
P2P Digital Currency
descriptor.cpp
Go to the documentation of this file.
1 // Copyright (c) 2018-2019 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 <script/descriptor.h>
6 
7 #include <key_io.h>
8 #include <pubkey.h>
9 #include <script/script.h>
10 #include <script/standard.h>
11 
12 #include <span.h>
13 #include <util/bip32.h>
14 #include <util/spanparsing.h>
15 #include <util/system.h>
16 #include <util/strencodings.h>
17 #include <util/vector.h>
18 
19 #include <memory>
20 #include <string>
21 #include <vector>
22 
23 namespace {
24 
26 // Checksum //
28 
29 // This section implements a checksum algorithm for descriptors with the
30 // following properties:
31 // * Mistakes in a descriptor string are measured in "symbol errors". The higher
32 // the number of symbol errors, the harder it is to detect:
33 // * An error substituting a character from 0123456789()[],'/*abcdefgh@:$%{} for
34 // another in that set always counts as 1 symbol error.
35 // * Note that hex encoded keys are covered by these characters. Xprvs and
36 // xpubs use other characters too, but already have their own checksum
37 // mechanism.
38 // * Function names like "multi()" use other characters, but mistakes in
39 // these would generally result in an unparsable descriptor.
40 // * A case error always counts as 1 symbol error.
41 // * Any other 1 character substitution error counts as 1 or 2 symbol errors.
42 // * Any 1 symbol error is always detected.
43 // * Any 2 or 3 symbol error in a descriptor of up to 49154 characters is always detected.
44 // * Any 4 symbol error in a descriptor of up to 507 characters is always detected.
45 // * Any 5 symbol error in a descriptor of up to 77 characters is always detected.
46 // * Is optimized to minimize the chance a 5 symbol error in a descriptor up to 387 characters is undetected
47 // * Random errors have a chance of 1 in 2**40 of being undetected.
48 //
49 // These properties are achieved by expanding every group of 3 (non checksum) characters into
50 // 4 GF(32) symbols, over which a cyclic code is defined.
51 
52 /*
53  * Interprets c as 8 groups of 5 bits which are the coefficients of a degree 8 polynomial over GF(32),
54  * multiplies that polynomial by x, computes its remainder modulo a generator, and adds the constant term val.
55  *
56  * This generator is G(x) = x^8 + {30}x^7 + {23}x^6 + {15}x^5 + {14}x^4 + {10}x^3 + {6}x^2 + {12}x + {9}.
57  * It is chosen to define an cyclic error detecting code which is selected by:
58  * - Starting from all BCH codes over GF(32) of degree 8 and below, which by construction guarantee detecting
59  * 3 errors in windows up to 19000 symbols.
60  * - Taking all those generators, and for degree 7 ones, extend them to degree 8 by adding all degree-1 factors.
61  * - Selecting just the set of generators that guarantee detecting 4 errors in a window of length 512.
62  * - Selecting one of those with best worst-case behavior for 5 errors in windows of length up to 512.
63  *
64  * The generator and the constants to implement it can be verified using this Sage code:
65  * B = GF(2) # Binary field
66  * BP.<b> = B[] # Polynomials over the binary field
67  * F_mod = b**5 + b**3 + 1
68  * F.<f> = GF(32, modulus=F_mod, repr='int') # GF(32) definition
69  * FP.<x> = F[] # Polynomials over GF(32)
70  * E_mod = x**3 + x + F.fetch_int(8)
71  * E.<e> = F.extension(E_mod) # Extension field definition
72  * alpha = e**2743 # Choice of an element in extension field
73  * for p in divisors(E.order() - 1): # Verify alpha has order 32767.
74  * assert((alpha**p == 1) == (p % 32767 == 0))
75  * G = lcm([(alpha**i).minpoly() for i in [1056,1057,1058]] + [x + 1])
76  * print(G) # Print out the generator
77  * for i in [1,2,4,8,16]: # Print out {1,2,4,8,16}*(G mod x^8), packed in hex integers.
78  * v = 0
79  * for coef in reversed((F.fetch_int(i)*(G % x**8)).coefficients(sparse=True)):
80  * v = v*32 + coef.integer_representation()
81  * print("0x%x" % v)
82  */
83 uint64_t PolyMod(uint64_t c, int val)
84 {
85  uint8_t c0 = c >> 35;
86  c = ((c & 0x7ffffffff) << 5) ^ val;
87  if (c0 & 1) c ^= 0xf5dee51989;
88  if (c0 & 2) c ^= 0xa9fdca3312;
89  if (c0 & 4) c ^= 0x1bab10e32d;
90  if (c0 & 8) c ^= 0x3706b1677a;
91  if (c0 & 16) c ^= 0x644d626ffd;
92  return c;
93 }
94 
95 std::string DescriptorChecksum(const Span<const char>& span)
96 {
110  static std::string INPUT_CHARSET =
111  "0123456789()[],'/*abcdefgh@:$%{}"
112  "IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~"
113  "ijklmnopqrstuvwxyzABCDEFGH`#\"\\ ";
114 
116  static std::string CHECKSUM_CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
117 
118  uint64_t c = 1;
119  int cls = 0;
120  int clscount = 0;
121  for (auto ch : span) {
122  auto pos = INPUT_CHARSET.find(ch);
123  if (pos == std::string::npos) return "";
124  c = PolyMod(c, pos & 31); // Emit a symbol for the position inside the group, for every character.
125  cls = cls * 3 + (pos >> 5); // Accumulate the group numbers
126  if (++clscount == 3) {
127  // Emit an extra symbol representing the group numbers, for every 3 characters.
128  c = PolyMod(c, cls);
129  cls = 0;
130  clscount = 0;
131  }
132  }
133  if (clscount > 0) c = PolyMod(c, cls);
134  for (int j = 0; j < 8; ++j) c = PolyMod(c, 0); // Shift further to determine the checksum.
135  c ^= 1; // Prevent appending zeroes from not affecting the checksum.
136 
137  std::string ret(8, ' ');
138  for (int j = 0; j < 8; ++j) ret[j] = CHECKSUM_CHARSET[(c >> (5 * (7 - j))) & 31];
139  return ret;
140 }
141 
142 std::string AddChecksum(const std::string& str) { return str + "#" + DescriptorChecksum(MakeSpan(str)); }
143 
145 // Internal representation //
147 
148 typedef std::vector<uint32_t> KeyPath;
149 
151 struct PubkeyProvider
152 {
153  virtual ~PubkeyProvider() = default;
154 
156  virtual bool GetPubKey(int pos, const SigningProvider& arg, CPubKey* key, KeyOriginInfo& info) const = 0;
157 
159  virtual bool IsRange() const = 0;
160 
162  virtual size_t GetSize() const = 0;
163 
165  virtual std::string ToString() const = 0;
166 
168  virtual bool ToPrivateString(const SigningProvider& arg, std::string& out) const = 0;
169 
171  virtual bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const = 0;
172 };
173 
174 class OriginPubkeyProvider final : public PubkeyProvider
175 {
176  KeyOriginInfo m_origin;
177  std::unique_ptr<PubkeyProvider> m_provider;
178 
179  std::string OriginString() const
180  {
181  return HexStr(std::begin(m_origin.fingerprint), std::end(m_origin.fingerprint)) + FormatHDKeypath(m_origin.path);
182  }
183 
184 public:
185  OriginPubkeyProvider(KeyOriginInfo info, std::unique_ptr<PubkeyProvider> provider) : m_origin(std::move(info)), m_provider(std::move(provider)) {}
186  bool GetPubKey(int pos, const SigningProvider& arg, CPubKey* key, KeyOriginInfo& info) const override
187  {
188  if (!m_provider->GetPubKey(pos, arg, key, info)) return false;
189  std::copy(std::begin(m_origin.fingerprint), std::end(m_origin.fingerprint), info.fingerprint);
190  info.path.insert(info.path.begin(), m_origin.path.begin(), m_origin.path.end());
191  return true;
192  }
193  bool IsRange() const override { return m_provider->IsRange(); }
194  size_t GetSize() const override { return m_provider->GetSize(); }
195  std::string ToString() const override { return "[" + OriginString() + "]" + m_provider->ToString(); }
196  bool ToPrivateString(const SigningProvider& arg, std::string& ret) const override
197  {
198  std::string sub;
199  if (!m_provider->ToPrivateString(arg, sub)) return false;
200  ret = "[" + OriginString() + "]" + std::move(sub);
201  return true;
202  }
203  bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const override
204  {
205  return m_provider->GetPrivKey(pos, arg, key);
206  }
207 };
208 
210 class ConstPubkeyProvider final : public PubkeyProvider
211 {
212  CPubKey m_pubkey;
213 
214 public:
215  ConstPubkeyProvider(const CPubKey& pubkey) : m_pubkey(pubkey) {}
216  bool GetPubKey(int pos, const SigningProvider& arg, CPubKey* key, KeyOriginInfo& info) const override
217  {
218  if (key) *key = m_pubkey;
219  info.path.clear();
220  CKeyID keyid = m_pubkey.GetID();
221  std::copy(keyid.begin(), keyid.begin() + sizeof(info.fingerprint), info.fingerprint);
222  return true;
223  }
224  bool IsRange() const override { return false; }
225  size_t GetSize() const override { return m_pubkey.size(); }
226  std::string ToString() const override { return HexStr(m_pubkey.begin(), m_pubkey.end()); }
227  bool ToPrivateString(const SigningProvider& arg, std::string& ret) const override
228  {
229  CKey key;
230  if (!arg.GetKey(m_pubkey.GetID(), key)) return false;
231  ret = EncodeSecret(key);
232  return true;
233  }
234  bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const override
235  {
236  return arg.GetKey(m_pubkey.GetID(), key);
237  }
238 };
239 
240 enum class DeriveType {
241  NO,
242  UNHARDENED,
243  HARDENED,
244 };
245 
247 class BIP32PubkeyProvider final : public PubkeyProvider
248 {
249  CExtPubKey m_extkey;
250  KeyPath m_path;
251  DeriveType m_derive;
252 
253  bool GetExtKey(const SigningProvider& arg, CExtKey& ret) const
254  {
255  CKey key;
256  if (!arg.GetKey(m_extkey.pubkey.GetID(), key)) return false;
257  ret.nDepth = m_extkey.nDepth;
258  std::copy(m_extkey.vchFingerprint, m_extkey.vchFingerprint + sizeof(ret.vchFingerprint), ret.vchFingerprint);
259  ret.nChild = m_extkey.nChild;
260  ret.chaincode = m_extkey.chaincode;
261  ret.key = key;
262  return true;
263  }
264 
265  bool IsHardened() const
266  {
267  if (m_derive == DeriveType::HARDENED) return true;
268  for (auto entry : m_path) {
269  if (entry >> 31) return true;
270  }
271  return false;
272  }
273 
274 public:
275  BIP32PubkeyProvider(const CExtPubKey& extkey, KeyPath path, DeriveType derive) : m_extkey(extkey), m_path(std::move(path)), m_derive(derive) {}
276  bool IsRange() const override { return m_derive != DeriveType::NO; }
277  size_t GetSize() const override { return 33; }
278  bool GetPubKey(int pos, const SigningProvider& arg, CPubKey* key, KeyOriginInfo& info) const override
279  {
280  if (key) {
281  if (IsHardened()) {
282  CKey priv_key;
283  if (!GetPrivKey(pos, arg, priv_key)) return false;
284  *key = priv_key.GetPubKey();
285  } else {
286  // TODO: optimize by caching
287  CExtPubKey extkey = m_extkey;
288  for (auto entry : m_path) {
289  extkey.Derive(extkey, entry);
290  }
291  if (m_derive == DeriveType::UNHARDENED) extkey.Derive(extkey, pos);
292  assert(m_derive != DeriveType::HARDENED);
293  *key = extkey.pubkey;
294  }
295  }
296  CKeyID keyid = m_extkey.pubkey.GetID();
297  std::copy(keyid.begin(), keyid.begin() + sizeof(info.fingerprint), info.fingerprint);
298  info.path = m_path;
299  if (m_derive == DeriveType::UNHARDENED) info.path.push_back((uint32_t)pos);
300  if (m_derive == DeriveType::HARDENED) info.path.push_back(((uint32_t)pos) | 0x80000000L);
301  return true;
302  }
303  std::string ToString() const override
304  {
305  std::string ret = EncodeExtPubKey(m_extkey) + FormatHDKeypath(m_path);
306  if (IsRange()) {
307  ret += "/*";
308  if (m_derive == DeriveType::HARDENED) ret += '\'';
309  }
310  return ret;
311  }
312  bool ToPrivateString(const SigningProvider& arg, std::string& out) const override
313  {
314  CExtKey key;
315  if (!GetExtKey(arg, key)) return false;
316  out = EncodeExtKey(key) + FormatHDKeypath(m_path);
317  if (IsRange()) {
318  out += "/*";
319  if (m_derive == DeriveType::HARDENED) out += '\'';
320  }
321  return true;
322  }
323  bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const override
324  {
325  CExtKey extkey;
326  if (!GetExtKey(arg, extkey)) return false;
327  for (auto entry : m_path) {
328  extkey.Derive(extkey, entry);
329  }
330  if (m_derive == DeriveType::UNHARDENED) extkey.Derive(extkey, pos);
331  if (m_derive == DeriveType::HARDENED) extkey.Derive(extkey, pos | 0x80000000UL);
332  key = extkey.key;
333  return true;
334  }
335 };
336 
338 class DescriptorImpl : public Descriptor
339 {
341  const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args;
345  const std::unique_ptr<DescriptorImpl> m_subdescriptor_arg;
347  const std::string m_name;
348 
349 protected:
351  virtual std::string ToStringExtra() const { return ""; }
352 
364  virtual std::vector<CScript> MakeScripts(const std::vector<CPubKey>& pubkeys, const CScript* script, FlatSigningProvider& out) const = 0;
365 
366 public:
367  DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, std::unique_ptr<DescriptorImpl> script, const std::string& name) : m_pubkey_args(std::move(pubkeys)), m_subdescriptor_arg(std::move(script)), m_name(name) {}
368 
369  bool IsSolvable() const override
370  {
371  if (m_subdescriptor_arg) {
372  if (!m_subdescriptor_arg->IsSolvable()) return false;
373  }
374  return true;
375  }
376 
377  bool IsRange() const final
378  {
379  for (const auto& pubkey : m_pubkey_args) {
380  if (pubkey->IsRange()) return true;
381  }
382  if (m_subdescriptor_arg) {
383  if (m_subdescriptor_arg->IsRange()) return true;
384  }
385  return false;
386  }
387 
388  bool ToStringHelper(const SigningProvider* arg, std::string& out, bool priv) const
389  {
390  std::string extra = ToStringExtra();
391  size_t pos = extra.size() > 0 ? 1 : 0;
392  std::string ret = m_name + "(" + extra;
393  for (const auto& pubkey : m_pubkey_args) {
394  if (pos++) ret += ",";
395  std::string tmp;
396  if (priv) {
397  if (!pubkey->ToPrivateString(*arg, tmp)) return false;
398  } else {
399  tmp = pubkey->ToString();
400  }
401  ret += std::move(tmp);
402  }
403  if (m_subdescriptor_arg) {
404  if (pos++) ret += ",";
405  std::string tmp;
406  if (!m_subdescriptor_arg->ToStringHelper(arg, tmp, priv)) return false;
407  ret += std::move(tmp);
408  }
409  out = std::move(ret) + ")";
410  return true;
411  }
412 
413  std::string ToString() const final
414  {
415  std::string ret;
416  ToStringHelper(nullptr, ret, false);
417  return AddChecksum(ret);
418  }
419 
420  bool ToPrivateString(const SigningProvider& arg, std::string& out) const override final
421  {
422  bool ret = ToStringHelper(&arg, out, true);
423  out = AddChecksum(out);
424  return ret;
425  }
426 
427  bool ExpandHelper(int pos, const SigningProvider& arg, Span<const unsigned char>* cache_read, std::vector<CScript>& output_scripts, FlatSigningProvider& out, std::vector<unsigned char>* cache_write) const
428  {
429  std::vector<std::pair<CPubKey, KeyOriginInfo>> entries;
430  entries.reserve(m_pubkey_args.size());
431 
432  // Construct temporary data in `entries` and `subscripts`, to avoid producing output in case of failure.
433  for (const auto& p : m_pubkey_args) {
434  entries.emplace_back();
435  // If we have a cache, we don't need GetPubKey to compute the public key.
436  // Pass in nullptr to signify only origin info is desired.
437  if (!p->GetPubKey(pos, arg, cache_read ? nullptr : &entries.back().first, entries.back().second)) return false;
438  if (cache_read) {
439  // Cached expanded public key exists, use it.
440  if (cache_read->size() == 0) return false;
441  bool compressed = ((*cache_read)[0] == 0x02 || (*cache_read)[0] == 0x03) && cache_read->size() >= 33;
442  bool uncompressed = ((*cache_read)[0] == 0x04) && cache_read->size() >= 65;
443  if (!(compressed || uncompressed)) return false;
444  CPubKey pubkey(cache_read->begin(), cache_read->begin() + (compressed ? 33 : 65));
445  entries.back().first = pubkey;
446  *cache_read = cache_read->subspan(compressed ? 33 : 65);
447  }
448  if (cache_write) {
449  cache_write->insert(cache_write->end(), entries.back().first.begin(), entries.back().first.end());
450  }
451  }
452  std::vector<CScript> subscripts;
453  if (m_subdescriptor_arg) {
454  FlatSigningProvider subprovider;
455  if (!m_subdescriptor_arg->ExpandHelper(pos, arg, cache_read, subscripts, subprovider, cache_write)) return false;
456  out = Merge(out, subprovider);
457  }
458 
459  std::vector<CPubKey> pubkeys;
460  pubkeys.reserve(entries.size());
461  for (auto& entry : entries) {
462  pubkeys.push_back(entry.first);
463  out.origins.emplace(entry.first.GetID(), std::make_pair<CPubKey, KeyOriginInfo>(CPubKey(entry.first), std::move(entry.second)));
464  }
465  if (m_subdescriptor_arg) {
466  for (const auto& subscript : subscripts) {
467  out.scripts.emplace(CScriptID(subscript), subscript);
468  std::vector<CScript> addscripts = MakeScripts(pubkeys, &subscript, out);
469  for (auto& addscript : addscripts) {
470  output_scripts.push_back(std::move(addscript));
471  }
472  }
473  } else {
474  output_scripts = MakeScripts(pubkeys, nullptr, out);
475  }
476  return true;
477  }
478 
479  bool Expand(int pos, const SigningProvider& provider, std::vector<CScript>& output_scripts, FlatSigningProvider& out, std::vector<unsigned char>* cache = nullptr) const final
480  {
481  return ExpandHelper(pos, provider, nullptr, output_scripts, out, cache);
482  }
483 
484  bool ExpandFromCache(int pos, const std::vector<unsigned char>& cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out) const final
485  {
486  Span<const unsigned char> span = MakeSpan(cache);
487  return ExpandHelper(pos, DUMMY_SIGNING_PROVIDER, &span, output_scripts, out, nullptr) && span.size() == 0;
488  }
489 
490  void ExpandPrivate(int pos, const SigningProvider& provider, FlatSigningProvider& out) const final
491  {
492  for (const auto& p : m_pubkey_args) {
493  CKey key;
494  if (!p->GetPrivKey(pos, provider, key)) continue;
495  out.keys.emplace(key.GetPubKey().GetID(), key);
496  }
497  if (m_subdescriptor_arg) {
498  FlatSigningProvider subprovider;
499  m_subdescriptor_arg->ExpandPrivate(pos, provider, subprovider);
500  out = Merge(out, subprovider);
501  }
502  }
503 };
504 
506 class AddressDescriptor final : public DescriptorImpl
507 {
508  const CTxDestination m_destination;
509 protected:
510  std::string ToStringExtra() const override { return EncodeDestination(m_destination); }
511  std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, const CScript*, FlatSigningProvider&) const override { return Vector(GetScriptForDestination(m_destination)); }
512 public:
513  AddressDescriptor(CTxDestination destination) : DescriptorImpl({}, {}, "addr"), m_destination(std::move(destination)) {}
514  bool IsSolvable() const final { return false; }
515 };
516 
518 class RawDescriptor final : public DescriptorImpl
519 {
520  const CScript m_script;
521 protected:
522  std::string ToStringExtra() const override { return HexStr(m_script.begin(), m_script.end()); }
523  std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, const CScript*, FlatSigningProvider&) const override { return Vector(m_script); }
524 public:
525  RawDescriptor(CScript script) : DescriptorImpl({}, {}, "raw"), m_script(std::move(script)) {}
526  bool IsSolvable() const final { return false; }
527 };
528 
530 class PKDescriptor final : public DescriptorImpl
531 {
532 protected:
533  std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, const CScript*, FlatSigningProvider&) const override { return Vector(GetScriptForRawPubKey(keys[0])); }
534 public:
535  PKDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), {}, "pk") {}
536 };
537 
539 class PKHDescriptor final : public DescriptorImpl
540 {
541 protected:
542  std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, const CScript*, FlatSigningProvider& out) const override
543  {
544  CKeyID id = keys[0].GetID();
545  out.pubkeys.emplace(id, keys[0]);
547  }
548 public:
549  PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), {}, "pkh") {}
550 };
551 
553 class WPKHDescriptor final : public DescriptorImpl
554 {
555 protected:
556  std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, const CScript*, FlatSigningProvider& out) const override
557  {
558  CKeyID id = keys[0].GetID();
559  out.pubkeys.emplace(id, keys[0]);
561  }
562 public:
563  WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), {}, "wpkh") {}
564 };
565 
567 class ComboDescriptor final : public DescriptorImpl
568 {
569 protected:
570  std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, const CScript*, FlatSigningProvider& out) const override
571  {
572  std::vector<CScript> ret;
573  CKeyID id = keys[0].GetID();
574  out.pubkeys.emplace(id, keys[0]);
575  ret.emplace_back(GetScriptForRawPubKey(keys[0])); // P2PK
576  ret.emplace_back(GetScriptForDestination(PKHash(id))); // P2PKH
577  if (keys[0].IsCompressed()) {
579  out.scripts.emplace(CScriptID(p2wpkh), p2wpkh);
580  ret.emplace_back(p2wpkh);
581  ret.emplace_back(GetScriptForDestination(ScriptHash(p2wpkh))); // P2SH-P2WPKH
582  }
583  return ret;
584  }
585 public:
586  ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), {}, "combo") {}
587 };
588 
590 class MultisigDescriptor final : public DescriptorImpl
591 {
592  const int m_threshold;
593  const bool m_sorted;
594 protected:
595  std::string ToStringExtra() const override { return strprintf("%i", m_threshold); }
596  std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, const CScript*, FlatSigningProvider&) const override {
597  if (m_sorted) {
598  std::vector<CPubKey> sorted_keys(keys);
599  std::sort(sorted_keys.begin(), sorted_keys.end());
600  return Vector(GetScriptForMultisig(m_threshold, sorted_keys));
601  }
602  return Vector(GetScriptForMultisig(m_threshold, keys));
603  }
604 public:
605  MultisigDescriptor(int threshold, std::vector<std::unique_ptr<PubkeyProvider>> providers, bool sorted = false) : DescriptorImpl(std::move(providers), {}, sorted ? "sortedmulti" : "multi"), m_threshold(threshold), m_sorted(sorted) {}
606 };
607 
609 class SHDescriptor final : public DescriptorImpl
610 {
611 protected:
612  std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, const CScript* script, FlatSigningProvider&) const override { return Vector(GetScriptForDestination(ScriptHash(*script))); }
613 public:
614  SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc), "sh") {}
615 };
616 
618 class WSHDescriptor final : public DescriptorImpl
619 {
620 protected:
621  std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, const CScript* script, FlatSigningProvider&) const override { return Vector(GetScriptForDestination(WitnessV0ScriptHash(*script))); }
622 public:
623  WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc), "wsh") {}
624 };
625 
627 // Parser //
629 
630 enum class ParseScriptContext {
631  TOP,
632  P2SH,
633  P2WSH,
634 };
635 
637 NODISCARD bool ParseKeyPath(const std::vector<Span<const char>>& split, KeyPath& out, std::string& error)
638 {
639  for (size_t i = 1; i < split.size(); ++i) {
640  Span<const char> elem = split[i];
641  bool hardened = false;
642  if (elem.size() > 0 && (elem[elem.size() - 1] == '\'' || elem[elem.size() - 1] == 'h')) {
643  elem = elem.first(elem.size() - 1);
644  hardened = true;
645  }
646  uint32_t p;
647  if (!ParseUInt32(std::string(elem.begin(), elem.end()), &p)) {
648  error = strprintf("Key path value '%s' is not a valid uint32", std::string(elem.begin(), elem.end()));
649  return false;
650  } else if (p > 0x7FFFFFFFUL) {
651  error = strprintf("Key path value %u is out of range", p);
652  return false;
653  }
654  out.push_back(p | (((uint32_t)hardened) << 31));
655  }
656  return true;
657 }
658 
660 std::unique_ptr<PubkeyProvider> ParsePubkeyInner(const Span<const char>& sp, bool permit_uncompressed, FlatSigningProvider& out, std::string& error)
661 {
662  using namespace spanparsing;
663 
664  auto split = Split(sp, '/');
665  std::string str(split[0].begin(), split[0].end());
666  if (str.size() == 0) {
667  error = "No key provided";
668  return nullptr;
669  }
670  if (split.size() == 1) {
671  if (IsHex(str)) {
672  std::vector<unsigned char> data = ParseHex(str);
673  CPubKey pubkey(data);
674  if (pubkey.IsFullyValid()) {
675  if (permit_uncompressed || pubkey.IsCompressed()) {
676  return MakeUnique<ConstPubkeyProvider>(pubkey);
677  } else {
678  error = "Uncompressed keys are not allowed";
679  return nullptr;
680  }
681  }
682  error = strprintf("Pubkey '%s' is invalid", str);
683  return nullptr;
684  }
685  CKey key = DecodeSecret(str);
686  if (key.IsValid()) {
687  if (permit_uncompressed || key.IsCompressed()) {
688  CPubKey pubkey = key.GetPubKey();
689  out.keys.emplace(pubkey.GetID(), key);
690  return MakeUnique<ConstPubkeyProvider>(pubkey);
691  } else {
692  error = "Uncompressed keys are not allowed";
693  return nullptr;
694  }
695  }
696  }
697  CExtKey extkey = DecodeExtKey(str);
698  CExtPubKey extpubkey = DecodeExtPubKey(str);
699  if (!extkey.key.IsValid() && !extpubkey.pubkey.IsValid()) {
700  error = strprintf("key '%s' is not valid", str);
701  return nullptr;
702  }
703  KeyPath path;
704  DeriveType type = DeriveType::NO;
705  if (split.back() == MakeSpan("*").first(1)) {
706  split.pop_back();
707  type = DeriveType::UNHARDENED;
708  } else if (split.back() == MakeSpan("*'").first(2) || split.back() == MakeSpan("*h").first(2)) {
709  split.pop_back();
710  type = DeriveType::HARDENED;
711  }
712  if (!ParseKeyPath(split, path, error)) return nullptr;
713  if (extkey.key.IsValid()) {
714  extpubkey = extkey.Neuter();
715  out.keys.emplace(extpubkey.pubkey.GetID(), extkey.key);
716  }
717  return MakeUnique<BIP32PubkeyProvider>(extpubkey, std::move(path), type);
718 }
719 
721 std::unique_ptr<PubkeyProvider> ParsePubkey(const Span<const char>& sp, bool permit_uncompressed, FlatSigningProvider& out, std::string& error)
722 {
723  using namespace spanparsing;
724 
725  auto origin_split = Split(sp, ']');
726  if (origin_split.size() > 2) {
727  error = "Multiple ']' characters found for a single pubkey";
728  return nullptr;
729  }
730  if (origin_split.size() == 1) return ParsePubkeyInner(origin_split[0], permit_uncompressed, out, error);
731  if (origin_split[0].size() < 1 || origin_split[0][0] != '[') {
732  error = strprintf("Key origin start '[ character expected but not found, got '%c' instead", origin_split[0][0]);
733  return nullptr;
734  }
735  auto slash_split = Split(origin_split[0].subspan(1), '/');
736  if (slash_split[0].size() != 8) {
737  error = strprintf("Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
738  return nullptr;
739  }
740  std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
741  if (!IsHex(fpr_hex)) {
742  error = strprintf("Fingerprint '%s' is not hex", fpr_hex);
743  return nullptr;
744  }
745  auto fpr_bytes = ParseHex(fpr_hex);
746  KeyOriginInfo info;
747  static_assert(sizeof(info.fingerprint) == 4, "Fingerprint must be 4 bytes");
748  assert(fpr_bytes.size() == 4);
749  std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.fingerprint);
750  if (!ParseKeyPath(slash_split, info.path, error)) return nullptr;
751  auto provider = ParsePubkeyInner(origin_split[1], permit_uncompressed, out, error);
752  if (!provider) return nullptr;
753  return MakeUnique<OriginPubkeyProvider>(std::move(info), std::move(provider));
754 }
755 
757 std::unique_ptr<DescriptorImpl> ParseScript(Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
758 {
759  using namespace spanparsing;
760 
761  auto expr = Expr(sp);
762  bool sorted_multi = false;
763  if (Func("pk", expr)) {
764  auto pubkey = ParsePubkey(expr, ctx != ParseScriptContext::P2WSH, out, error);
765  if (!pubkey) return nullptr;
766  return MakeUnique<PKDescriptor>(std::move(pubkey));
767  }
768  if (Func("pkh", expr)) {
769  auto pubkey = ParsePubkey(expr, ctx != ParseScriptContext::P2WSH, out, error);
770  if (!pubkey) return nullptr;
771  return MakeUnique<PKHDescriptor>(std::move(pubkey));
772  }
773  if (ctx == ParseScriptContext::TOP && Func("combo", expr)) {
774  auto pubkey = ParsePubkey(expr, true, out, error);
775  if (!pubkey) return nullptr;
776  return MakeUnique<ComboDescriptor>(std::move(pubkey));
777  } else if (ctx != ParseScriptContext::TOP && Func("combo", expr)) {
778  error = "Cannot have combo in non-top level";
779  return nullptr;
780  }
781  if ((sorted_multi = Func("sortedmulti", expr)) || Func("multi", expr)) {
782  auto threshold = Expr(expr);
783  uint32_t thres;
784  std::vector<std::unique_ptr<PubkeyProvider>> providers;
785  if (!ParseUInt32(std::string(threshold.begin(), threshold.end()), &thres)) {
786  error = strprintf("Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
787  return nullptr;
788  }
789  size_t script_size = 0;
790  while (expr.size()) {
791  if (!Const(",", expr)) {
792  error = strprintf("Multi: expected ',', got '%c'", expr[0]);
793  return nullptr;
794  }
795  auto arg = Expr(expr);
796  auto pk = ParsePubkey(arg, ctx != ParseScriptContext::P2WSH, out, error);
797  if (!pk) return nullptr;
798  script_size += pk->GetSize() + 1;
799  providers.emplace_back(std::move(pk));
800  }
801  if (providers.size() < 1 || providers.size() > 16) {
802  error = strprintf("Cannot have %u keys in multisig; must have between 1 and 16 keys, inclusive", providers.size());
803  return nullptr;
804  } else if (thres < 1) {
805  error = strprintf("Multisig threshold cannot be %d, must be at least 1", thres);
806  return nullptr;
807  } else if (thres > providers.size()) {
808  error = strprintf("Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
809  return nullptr;
810  }
811  if (ctx == ParseScriptContext::TOP) {
812  if (providers.size() > 3) {
813  error = strprintf("Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
814  return nullptr;
815  }
816  }
817  if (ctx == ParseScriptContext::P2SH) {
818  if (script_size + 3 > MAX_SCRIPT_ELEMENT_SIZE) {
819  error = strprintf("P2SH script is too large, %d bytes is larger than %d bytes", script_size + 3, MAX_SCRIPT_ELEMENT_SIZE);
820  return nullptr;
821  }
822  }
823  return MakeUnique<MultisigDescriptor>(thres, std::move(providers), sorted_multi);
824  }
825  if (ctx != ParseScriptContext::P2WSH && Func("wpkh", expr)) {
826  auto pubkey = ParsePubkey(expr, false, out, error);
827  if (!pubkey) return nullptr;
828  return MakeUnique<WPKHDescriptor>(std::move(pubkey));
829  } else if (ctx == ParseScriptContext::P2WSH && Func("wpkh", expr)) {
830  error = "Cannot have wpkh within wsh";
831  return nullptr;
832  }
833  if (ctx == ParseScriptContext::TOP && Func("sh", expr)) {
834  auto desc = ParseScript(expr, ParseScriptContext::P2SH, out, error);
835  if (!desc || expr.size()) return nullptr;
836  return MakeUnique<SHDescriptor>(std::move(desc));
837  } else if (ctx != ParseScriptContext::TOP && Func("sh", expr)) {
838  error = "Cannot have sh in non-top level";
839  return nullptr;
840  }
841  if (ctx != ParseScriptContext::P2WSH && Func("wsh", expr)) {
842  auto desc = ParseScript(expr, ParseScriptContext::P2WSH, out, error);
843  if (!desc || expr.size()) return nullptr;
844  return MakeUnique<WSHDescriptor>(std::move(desc));
845  } else if (ctx == ParseScriptContext::P2WSH && Func("wsh", expr)) {
846  error = "Cannot have wsh within wsh";
847  return nullptr;
848  }
849  if (ctx == ParseScriptContext::TOP && Func("addr", expr)) {
850  CTxDestination dest = DecodeDestination(std::string(expr.begin(), expr.end()));
851  if (!IsValidDestination(dest)) {
852  error = "Address is not valid";
853  return nullptr;
854  }
855  return MakeUnique<AddressDescriptor>(std::move(dest));
856  }
857  if (ctx == ParseScriptContext::TOP && Func("raw", expr)) {
858  std::string str(expr.begin(), expr.end());
859  if (!IsHex(str)) {
860  error = "Raw script is not hex";
861  return nullptr;
862  }
863  auto bytes = ParseHex(str);
864  return MakeUnique<RawDescriptor>(CScript(bytes.begin(), bytes.end()));
865  }
866  if (ctx == ParseScriptContext::P2SH) {
867  error = "A function is needed within P2SH";
868  return nullptr;
869  } else if (ctx == ParseScriptContext::P2WSH) {
870  error = "A function is needed within P2WSH";
871  return nullptr;
872  }
873  error = strprintf("%s is not a valid descriptor function", std::string(expr.begin(), expr.end()));
874  return nullptr;
875 }
876 
877 std::unique_ptr<PubkeyProvider> InferPubkey(const CPubKey& pubkey, ParseScriptContext, const SigningProvider& provider)
878 {
879  std::unique_ptr<PubkeyProvider> key_provider = MakeUnique<ConstPubkeyProvider>(pubkey);
880  KeyOriginInfo info;
881  if (provider.GetKeyOrigin(pubkey.GetID(), info)) {
882  return MakeUnique<OriginPubkeyProvider>(std::move(info), std::move(key_provider));
883  }
884  return key_provider;
885 }
886 
887 std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptContext ctx, const SigningProvider& provider)
888 {
889  std::vector<std::vector<unsigned char>> data;
890  txnouttype txntype = Solver(script, data);
891 
892  if (txntype == TX_PUBKEY) {
893  CPubKey pubkey(data[0].begin(), data[0].end());
894  if (pubkey.IsValid()) {
895  return MakeUnique<PKDescriptor>(InferPubkey(pubkey, ctx, provider));
896  }
897  }
898  if (txntype == TX_PUBKEYHASH) {
899  uint160 hash(data[0]);
900  CKeyID keyid(hash);
901  CPubKey pubkey;
902  if (provider.GetPubKey(keyid, pubkey)) {
903  return MakeUnique<PKHDescriptor>(InferPubkey(pubkey, ctx, provider));
904  }
905  }
906  if (txntype == TX_WITNESS_V0_KEYHASH && ctx != ParseScriptContext::P2WSH) {
907  uint160 hash(data[0]);
908  CKeyID keyid(hash);
909  CPubKey pubkey;
910  if (provider.GetPubKey(keyid, pubkey)) {
911  return MakeUnique<WPKHDescriptor>(InferPubkey(pubkey, ctx, provider));
912  }
913  }
914  if (txntype == TX_MULTISIG) {
915  std::vector<std::unique_ptr<PubkeyProvider>> providers;
916  for (size_t i = 1; i + 1 < data.size(); ++i) {
917  CPubKey pubkey(data[i].begin(), data[i].end());
918  providers.push_back(InferPubkey(pubkey, ctx, provider));
919  }
920  return MakeUnique<MultisigDescriptor>((int)data[0][0], std::move(providers));
921  }
922  if (txntype == TX_SCRIPTHASH && ctx == ParseScriptContext::TOP) {
923  uint160 hash(data[0]);
924  CScriptID scriptid(hash);
925  CScript subscript;
926  if (provider.GetCScript(scriptid, subscript)) {
927  auto sub = InferScript(subscript, ParseScriptContext::P2SH, provider);
928  if (sub) return MakeUnique<SHDescriptor>(std::move(sub));
929  }
930  }
931  if (txntype == TX_WITNESS_V0_SCRIPTHASH && ctx != ParseScriptContext::P2WSH) {
932  CScriptID scriptid;
933  CRIPEMD160().Write(data[0].data(), data[0].size()).Finalize(scriptid.begin());
934  CScript subscript;
935  if (provider.GetCScript(scriptid, subscript)) {
936  auto sub = InferScript(subscript, ParseScriptContext::P2WSH, provider);
937  if (sub) return MakeUnique<WSHDescriptor>(std::move(sub));
938  }
939  }
940 
941  CTxDestination dest;
942  if (ExtractDestination(script, dest)) {
943  if (GetScriptForDestination(dest) == script) {
944  return MakeUnique<AddressDescriptor>(std::move(dest));
945  }
946  }
947 
948  return MakeUnique<RawDescriptor>(script);
949 }
950 
951 
952 } // namespace
953 
955 bool CheckChecksum(Span<const char>& sp, bool require_checksum, std::string& error, std::string* out_checksum = nullptr)
956 {
957  using namespace spanparsing;
958 
959  auto check_split = Split(sp, '#');
960  if (check_split.size() > 2) {
961  error = "Multiple '#' symbols";
962  return false;
963  }
964  if (check_split.size() == 1 && require_checksum){
965  error = "Missing checksum";
966  return false;
967  }
968  if (check_split.size() == 2) {
969  if (check_split[1].size() != 8) {
970  error = strprintf("Expected 8 character checksum, not %u characters", check_split[1].size());
971  return false;
972  }
973  }
974  auto checksum = DescriptorChecksum(check_split[0]);
975  if (checksum.empty()) {
976  error = "Invalid characters in payload";
977  return false;
978  }
979  if (check_split.size() == 2) {
980  if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
981  error = strprintf("Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
982  return false;
983  }
984  }
985  if (out_checksum) *out_checksum = std::move(checksum);
986  sp = check_split[0];
987  return true;
988 }
989 
990 std::unique_ptr<Descriptor> Parse(const std::string& descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum)
991 {
992  Span<const char> sp(descriptor.data(), descriptor.size());
993  if (!CheckChecksum(sp, require_checksum, error)) return nullptr;
994  auto ret = ParseScript(sp, ParseScriptContext::TOP, out, error);
995  if (sp.size() == 0 && ret) return std::unique_ptr<Descriptor>(std::move(ret));
996  return nullptr;
997 }
998 
999 std::string GetDescriptorChecksum(const std::string& descriptor)
1000 {
1001  std::string ret;
1002  std::string error;
1003  Span<const char> sp(descriptor.data(), descriptor.size());
1004  if (!CheckChecksum(sp, false, error, &ret)) return "";
1005  return ret;
1006 }
1007 
1008 std::unique_ptr<Descriptor> InferDescriptor(const CScript& script, const SigningProvider& provider)
1009 {
1010  return InferScript(script, ParseScriptContext::TOP, provider);
1011 }
Top-level scriptPubKey.
constexpr std::ptrdiff_t size() const noexcept
Definition: span.h:30
bool CheckChecksum(Span< const char > &sp, bool require_checksum, std::string &error, std::string *out_checksum=nullptr)
Check a descriptor checksum, and update desc to be the checksum-less part.
Definition: descriptor.cpp:955
unsigned char fingerprint[4]
First 32 bits of the Hash160 of the public key at the root of the path.
Definition: keyorigin.h:13
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
Definition: standard.cpp:156
bool Func(const std::string &str, Span< const char > &sp)
Parse a function call.
Definition: spanparsing.cpp:23
constexpr C * end() const noexcept
Definition: span.h:29
CKey key
Definition: key.h:149
bool Derive(CExtKey &out, unsigned int nChild) const
Definition: key.cpp:293
DeriveType
Definition: descriptor.cpp:240
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:184
std::map< CKeyID, CKey > keys
bool ParseUInt32(const std::string &str, uint32_t *out)
Convert decimal string to unsigned 32-bit integer with strict parse error feedback.
CExtKey DecodeExtKey(const std::string &str)
Definition: key_io.cpp:186
FlatSigningProvider Merge(const FlatSigningProvider &a, const FlatSigningProvider &b)
std::string GetDescriptorChecksum(const std::string &descriptor)
Get the checksum for a descriptor.
Definition: descriptor.cpp:999
Definition: key.h:144
bool Const(const std::string &str, Span< const char > &sp)
Parse a constant.
Definition: spanparsing.cpp:14
std::vector< unsigned char > ParseHex(const char *psz)
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
Definition: standard.cpp:325
unsigned char vchFingerprint[4]
Definition: key.h:146
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
Definition: standard.cpp:297
std::map< CKeyID, std::pair< CPubKey, KeyOriginInfo > > origins
std::string FormatHDKeypath(const std::vector< uint32_t > &path)
Definition: bip32.cpp:53
txnouttype Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char >> &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
Definition: standard.cpp:91
std::vector< Span< const char > > Split(const Span< const char > &sp, char sep)
Split a string on every instance of sep, returning a vector.
Definition: spanparsing.cpp:51
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
Definition: script.h:23
constexpr Span< A > MakeSpan(A(&a)[N])
Create a span to a container exposing data() and size().
Definition: span.h:55
unsigned char * begin()
Definition: uint256.h:54
CExtPubKey DecodeExtPubKey(const std::string &str)
Definition: key_io.cpp:163
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:155
Span< const char > Expr(Span< const char > &sp)
Extract the expression that sp begins with.
Definition: spanparsing.cpp:32
std::vector< typename std::common_type< Args... >::type > Vector(Args &&... args)
Construct a vector with the specified elements.
Definition: vector.h:20
std::unique_ptr< Descriptor > Parse(const std::string &descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
Definition: descriptor.cpp:990
constexpr Span< C > subspan(std::ptrdiff_t offset) const noexcept
Definition: span.h:33
virtual bool GetPubKey(const CKeyID &address, CPubKey &pubkey) const
bool IsFullyValid() const
fully validate whether this is a valid public key (more expensive than IsValid()) ...
Definition: pubkey.cpp:208
std::map< CScriptID, CScript > scripts
#define NODISCARD
Definition: attributes.h:18
virtual bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const
const char * name
Definition: rest.cpp:40
unsigned char nDepth
Definition: key.h:145
const SigningProvider & DUMMY_SIGNING_PROVIDER
static secp256k1_context * ctx
Definition: tests.c:46
bool IsValid() const
Definition: pubkey.h:171
An encapsulated public key.
Definition: pubkey.h:30
bool IsHex(const std::string &str)
std::map< CKeyID, CPubKey > pubkeys
unsigned int nChild
Definition: key.h:147
ParseScriptContext
Definition: descriptor.cpp:630
constexpr Span< C > first(std::ptrdiff_t count) const noexcept
Definition: span.h:35
bool IsCompressed() const
Check whether the public key corresponding to this private key is (to be) compressed.
Definition: key.h:96
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
Definition: standard.cpp:289
ChainCode chaincode
Definition: key.h:148
virtual bool GetCScript(const CScriptID &scriptid, CScript &script) const
virtual bool GetKey(const CKeyID &address, CKey &key) const
bool IsSolvable(const SigningProvider &provider, const CScript &script)
Definition: sign.cpp:434
CRIPEMD160 & Write(const unsigned char *data, size_t len)
Definition: ripemd160.cpp:247
P2SH redeemScript.
constexpr C * begin() const noexcept
Definition: span.h:28
txnouttype
Definition: standard.h:55
CTxDestination DecodeDestination(const std::string &str)
Definition: key_io.cpp:215
bool Derive(CExtPubKey &out, unsigned int nChild) const
Definition: pubkey.cpp:271
std::string EncodeExtPubKey(const CExtPubKey &key)
Definition: key_io.cpp:176
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible...
An interface to be implemented by keystores that support signing.
CExtPubKey Neuter() const
Definition: key.cpp:312
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:390
static bool GetPubKey(const SigningProvider &provider, const SignatureData &sigdata, const CKeyID &address, CPubKey &pubkey)
Definition: sign.cpp:52
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:20
std::string HexStr(const T itbegin, const T itend)
Definition: strencodings.h:125
160-bit opaque blob.
Definition: uint256.h:109
A reference to a CScript: the Hash160 of its serialization (see script.h)
Definition: standard.h:21
std::string EncodeDestination(const CTxDestination &dest)
Definition: key_io.cpp:210
CPubKey pubkey
Definition: pubkey.h:211
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
Definition: standard.cpp:302
An encapsulated private key.
Definition: key.h:27
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:17
CKey DecodeSecret(const std::string &str)
Definition: key_io.cpp:132
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: ripemd160.cpp:273
boost::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:143
CScript ParseScript(const std::string &s)
Definition: core_read.cpp:23
std::string EncodeSecret(const CKey &key)
Definition: key_io.cpp:150
std::vector< uint32_t > path
Definition: keyorigin.h:14
bool error(const char *fmt, const Args &... args)
Definition: system.h:49
std::string EncodeExtKey(const CExtKey &key)
Definition: key_io.cpp:199
Interface for parsed descriptor objects.
Definition: descriptor.h:32
A hasher class for RIPEMD-160.
Definition: ripemd160.h:12
bool IsValid() const
Check whether this private key is valid.
Definition: key.h:93
bool IsCompressed() const
Check whether this is a compressed public key.
Definition: pubkey.h:180