Bitcoin Core  0.20.99
P2P Digital Currency
descriptor.cpp
Go to the documentation of this file.
1 // Copyright (c) 2018-2020 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(str); }
143 
145 // Internal representation //
147 
148 typedef std::vector<uint32_t> KeyPath;
149 
151 struct PubkeyProvider
152 {
153 protected:
156  uint32_t m_expr_index;
157 
158 public:
159  PubkeyProvider(uint32_t exp_index) : m_expr_index(exp_index) {}
160 
161  virtual ~PubkeyProvider() = default;
162 
168  virtual bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key, KeyOriginInfo& info, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) = 0;
169 
171  virtual bool IsRange() const = 0;
172 
174  virtual size_t GetSize() const = 0;
175 
177  virtual std::string ToString() const = 0;
178 
180  virtual bool ToPrivateString(const SigningProvider& arg, std::string& out) const = 0;
181 
183  virtual bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const = 0;
184 };
185 
186 class OriginPubkeyProvider final : public PubkeyProvider
187 {
188  KeyOriginInfo m_origin;
189  std::unique_ptr<PubkeyProvider> m_provider;
190 
191  std::string OriginString() const
192  {
193  return HexStr(std::begin(m_origin.fingerprint), std::end(m_origin.fingerprint)) + FormatHDKeypath(m_origin.path);
194  }
195 
196 public:
197  OriginPubkeyProvider(uint32_t exp_index, KeyOriginInfo info, std::unique_ptr<PubkeyProvider> provider) : PubkeyProvider(exp_index), m_origin(std::move(info)), m_provider(std::move(provider)) {}
198  bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key, KeyOriginInfo& info, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) override
199  {
200  if (!m_provider->GetPubKey(pos, arg, key, info, read_cache, write_cache)) return false;
201  std::copy(std::begin(m_origin.fingerprint), std::end(m_origin.fingerprint), info.fingerprint);
202  info.path.insert(info.path.begin(), m_origin.path.begin(), m_origin.path.end());
203  return true;
204  }
205  bool IsRange() const override { return m_provider->IsRange(); }
206  size_t GetSize() const override { return m_provider->GetSize(); }
207  std::string ToString() const override { return "[" + OriginString() + "]" + m_provider->ToString(); }
208  bool ToPrivateString(const SigningProvider& arg, std::string& ret) const override
209  {
210  std::string sub;
211  if (!m_provider->ToPrivateString(arg, sub)) return false;
212  ret = "[" + OriginString() + "]" + std::move(sub);
213  return true;
214  }
215  bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const override
216  {
217  return m_provider->GetPrivKey(pos, arg, key);
218  }
219 };
220 
222 class ConstPubkeyProvider final : public PubkeyProvider
223 {
224  CPubKey m_pubkey;
225 
226 public:
227  ConstPubkeyProvider(uint32_t exp_index, const CPubKey& pubkey) : PubkeyProvider(exp_index), m_pubkey(pubkey) {}
228  bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key, KeyOriginInfo& info, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) override
229  {
230  key = m_pubkey;
231  info.path.clear();
232  CKeyID keyid = m_pubkey.GetID();
233  std::copy(keyid.begin(), keyid.begin() + sizeof(info.fingerprint), info.fingerprint);
234  return true;
235  }
236  bool IsRange() const override { return false; }
237  size_t GetSize() const override { return m_pubkey.size(); }
238  std::string ToString() const override { return HexStr(m_pubkey); }
239  bool ToPrivateString(const SigningProvider& arg, std::string& ret) const override
240  {
241  CKey key;
242  if (!arg.GetKey(m_pubkey.GetID(), key)) return false;
243  ret = EncodeSecret(key);
244  return true;
245  }
246  bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const override
247  {
248  return arg.GetKey(m_pubkey.GetID(), key);
249  }
250 };
251 
252 enum class DeriveType {
253  NO,
254  UNHARDENED,
255  HARDENED,
256 };
257 
259 class BIP32PubkeyProvider final : public PubkeyProvider
260 {
261  // Root xpub, path, and final derivation step type being used, if any
262  CExtPubKey m_root_extkey;
263  KeyPath m_path;
264  DeriveType m_derive;
265  // Cache of the parent of the final derived pubkeys.
266  // Primarily useful for situations when no read_cache is provided
267  CExtPubKey m_cached_xpub;
268 
269  bool GetExtKey(const SigningProvider& arg, CExtKey& ret) const
270  {
271  CKey key;
272  if (!arg.GetKey(m_root_extkey.pubkey.GetID(), key)) return false;
273  ret.nDepth = m_root_extkey.nDepth;
274  std::copy(m_root_extkey.vchFingerprint, m_root_extkey.vchFingerprint + sizeof(ret.vchFingerprint), ret.vchFingerprint);
275  ret.nChild = m_root_extkey.nChild;
276  ret.chaincode = m_root_extkey.chaincode;
277  ret.key = key;
278  return true;
279  }
280 
281  // Derives the last xprv
282  bool GetDerivedExtKey(const SigningProvider& arg, CExtKey& xprv) const
283  {
284  if (!GetExtKey(arg, xprv)) return false;
285  for (auto entry : m_path) {
286  xprv.Derive(xprv, entry);
287  }
288  return true;
289  }
290 
291  bool IsHardened() const
292  {
293  if (m_derive == DeriveType::HARDENED) return true;
294  for (auto entry : m_path) {
295  if (entry >> 31) return true;
296  }
297  return false;
298  }
299 
300 public:
301  BIP32PubkeyProvider(uint32_t exp_index, const CExtPubKey& extkey, KeyPath path, DeriveType derive) : PubkeyProvider(exp_index), m_root_extkey(extkey), m_path(std::move(path)), m_derive(derive) {}
302  bool IsRange() const override { return m_derive != DeriveType::NO; }
303  size_t GetSize() const override { return 33; }
304  bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key_out, KeyOriginInfo& final_info_out, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) override
305  {
306  // Info of parent of the to be derived pubkey
307  KeyOriginInfo parent_info;
308  CKeyID keyid = m_root_extkey.pubkey.GetID();
309  std::copy(keyid.begin(), keyid.begin() + sizeof(parent_info.fingerprint), parent_info.fingerprint);
310  parent_info.path = m_path;
311 
312  // Info of the derived key itself which is copied out upon successful completion
313  KeyOriginInfo final_info_out_tmp = parent_info;
314  if (m_derive == DeriveType::UNHARDENED) final_info_out_tmp.path.push_back((uint32_t)pos);
315  if (m_derive == DeriveType::HARDENED) final_info_out_tmp.path.push_back(((uint32_t)pos) | 0x80000000L);
316 
317  // Derive keys or fetch them from cache
318  CExtPubKey final_extkey = m_root_extkey;
319  CExtPubKey parent_extkey = m_root_extkey;
320  bool der = true;
321  if (read_cache) {
322  if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
323  if (m_derive == DeriveType::HARDENED) return false;
324  // Try to get the derivation parent
325  if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey)) return false;
326  final_extkey = parent_extkey;
327  if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.Derive(final_extkey, pos);
328  }
329  } else if (m_cached_xpub.pubkey.IsValid() && m_derive != DeriveType::HARDENED) {
330  parent_extkey = final_extkey = m_cached_xpub;
331  if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.Derive(final_extkey, pos);
332  } else if (IsHardened()) {
333  CExtKey xprv;
334  if (!GetDerivedExtKey(arg, xprv)) return false;
335  parent_extkey = xprv.Neuter();
336  if (m_derive == DeriveType::UNHARDENED) der = xprv.Derive(xprv, pos);
337  if (m_derive == DeriveType::HARDENED) der = xprv.Derive(xprv, pos | 0x80000000UL);
338  final_extkey = xprv.Neuter();
339  } else {
340  for (auto entry : m_path) {
341  der = parent_extkey.Derive(parent_extkey, entry);
342  assert(der);
343  }
344  final_extkey = parent_extkey;
345  if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.Derive(final_extkey, pos);
346  assert(m_derive != DeriveType::HARDENED);
347  }
348  assert(der);
349 
350  final_info_out = final_info_out_tmp;
351  key_out = final_extkey.pubkey;
352 
353  // We rely on the consumer to check that m_derive isn't HARDENED as above
354  // But we can't have already cached something in case we read something from the cache
355  // and parent_extkey isn't actually the parent.
356  if (!m_cached_xpub.pubkey.IsValid()) m_cached_xpub = parent_extkey;
357 
358  if (write_cache) {
359  // Only cache parent if there is any unhardened derivation
360  if (m_derive != DeriveType::HARDENED) {
361  write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
362  } else if (final_info_out.path.size() > 0) {
363  write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey);
364  }
365  }
366 
367  return true;
368  }
369  std::string ToString() const override
370  {
371  std::string ret = EncodeExtPubKey(m_root_extkey) + FormatHDKeypath(m_path);
372  if (IsRange()) {
373  ret += "/*";
374  if (m_derive == DeriveType::HARDENED) ret += '\'';
375  }
376  return ret;
377  }
378  bool ToPrivateString(const SigningProvider& arg, std::string& out) const override
379  {
380  CExtKey key;
381  if (!GetExtKey(arg, key)) return false;
382  out = EncodeExtKey(key) + FormatHDKeypath(m_path);
383  if (IsRange()) {
384  out += "/*";
385  if (m_derive == DeriveType::HARDENED) out += '\'';
386  }
387  return true;
388  }
389  bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const override
390  {
391  CExtKey extkey;
392  if (!GetDerivedExtKey(arg, extkey)) return false;
393  if (m_derive == DeriveType::UNHARDENED) extkey.Derive(extkey, pos);
394  if (m_derive == DeriveType::HARDENED) extkey.Derive(extkey, pos | 0x80000000UL);
395  key = extkey.key;
396  return true;
397  }
398 };
399 
401 class DescriptorImpl : public Descriptor
402 {
404  const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args;
406  const std::string m_name;
407 
408 protected:
412  const std::unique_ptr<DescriptorImpl> m_subdescriptor_arg;
413 
415  virtual std::string ToStringExtra() const { return ""; }
416 
428  virtual std::vector<CScript> MakeScripts(const std::vector<CPubKey>& pubkeys, const CScript* script, FlatSigningProvider& out) const = 0;
429 
430 public:
431  DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, std::unique_ptr<DescriptorImpl> script, const std::string& name) : m_pubkey_args(std::move(pubkeys)), m_name(name), m_subdescriptor_arg(std::move(script)) {}
432 
433  bool IsSolvable() const override
434  {
435  if (m_subdescriptor_arg) {
436  if (!m_subdescriptor_arg->IsSolvable()) return false;
437  }
438  return true;
439  }
440 
441  bool IsRange() const final
442  {
443  for (const auto& pubkey : m_pubkey_args) {
444  if (pubkey->IsRange()) return true;
445  }
446  if (m_subdescriptor_arg) {
447  if (m_subdescriptor_arg->IsRange()) return true;
448  }
449  return false;
450  }
451 
452  bool ToStringHelper(const SigningProvider* arg, std::string& out, bool priv) const
453  {
454  std::string extra = ToStringExtra();
455  size_t pos = extra.size() > 0 ? 1 : 0;
456  std::string ret = m_name + "(" + extra;
457  for (const auto& pubkey : m_pubkey_args) {
458  if (pos++) ret += ",";
459  std::string tmp;
460  if (priv) {
461  if (!pubkey->ToPrivateString(*arg, tmp)) return false;
462  } else {
463  tmp = pubkey->ToString();
464  }
465  ret += std::move(tmp);
466  }
467  if (m_subdescriptor_arg) {
468  if (pos++) ret += ",";
469  std::string tmp;
470  if (!m_subdescriptor_arg->ToStringHelper(arg, tmp, priv)) return false;
471  ret += std::move(tmp);
472  }
473  out = std::move(ret) + ")";
474  return true;
475  }
476 
477  std::string ToString() const final
478  {
479  std::string ret;
480  ToStringHelper(nullptr, ret, false);
481  return AddChecksum(ret);
482  }
483 
484  bool ToPrivateString(const SigningProvider& arg, std::string& out) const final
485  {
486  bool ret = ToStringHelper(&arg, out, true);
487  out = AddChecksum(out);
488  return ret;
489  }
490 
491  bool ExpandHelper(int pos, const SigningProvider& arg, const DescriptorCache* read_cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out, DescriptorCache* write_cache) const
492  {
493  std::vector<std::pair<CPubKey, KeyOriginInfo>> entries;
494  entries.reserve(m_pubkey_args.size());
495 
496  // Construct temporary data in `entries` and `subscripts`, to avoid producing output in case of failure.
497  for (const auto& p : m_pubkey_args) {
498  entries.emplace_back();
499  if (!p->GetPubKey(pos, arg, entries.back().first, entries.back().second, read_cache, write_cache)) return false;
500  }
501  std::vector<CScript> subscripts;
502  if (m_subdescriptor_arg) {
503  FlatSigningProvider subprovider;
504  if (!m_subdescriptor_arg->ExpandHelper(pos, arg, read_cache, subscripts, subprovider, write_cache)) return false;
505  out = Merge(out, subprovider);
506  }
507 
508  std::vector<CPubKey> pubkeys;
509  pubkeys.reserve(entries.size());
510  for (auto& entry : entries) {
511  pubkeys.push_back(entry.first);
512  out.origins.emplace(entry.first.GetID(), std::make_pair<CPubKey, KeyOriginInfo>(CPubKey(entry.first), std::move(entry.second)));
513  }
514  if (m_subdescriptor_arg) {
515  for (const auto& subscript : subscripts) {
516  out.scripts.emplace(CScriptID(subscript), subscript);
517  std::vector<CScript> addscripts = MakeScripts(pubkeys, &subscript, out);
518  for (auto& addscript : addscripts) {
519  output_scripts.push_back(std::move(addscript));
520  }
521  }
522  } else {
523  output_scripts = MakeScripts(pubkeys, nullptr, out);
524  }
525  return true;
526  }
527 
528  bool Expand(int pos, const SigningProvider& provider, std::vector<CScript>& output_scripts, FlatSigningProvider& out, DescriptorCache* write_cache = nullptr) const final
529  {
530  return ExpandHelper(pos, provider, nullptr, output_scripts, out, write_cache);
531  }
532 
533  bool ExpandFromCache(int pos, const DescriptorCache& read_cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out) const final
534  {
535  return ExpandHelper(pos, DUMMY_SIGNING_PROVIDER, &read_cache, output_scripts, out, nullptr);
536  }
537 
538  void ExpandPrivate(int pos, const SigningProvider& provider, FlatSigningProvider& out) const final
539  {
540  for (const auto& p : m_pubkey_args) {
541  CKey key;
542  if (!p->GetPrivKey(pos, provider, key)) continue;
543  out.keys.emplace(key.GetPubKey().GetID(), key);
544  }
545  if (m_subdescriptor_arg) {
546  FlatSigningProvider subprovider;
547  m_subdescriptor_arg->ExpandPrivate(pos, provider, subprovider);
548  out = Merge(out, subprovider);
549  }
550  }
551 
552  Optional<OutputType> GetOutputType() const override { return nullopt; }
553 };
554 
556 class AddressDescriptor final : public DescriptorImpl
557 {
558  const CTxDestination m_destination;
559 protected:
560  std::string ToStringExtra() const override { return EncodeDestination(m_destination); }
561  std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, const CScript*, FlatSigningProvider&) const override { return Vector(GetScriptForDestination(m_destination)); }
562 public:
563  AddressDescriptor(CTxDestination destination) : DescriptorImpl({}, {}, "addr"), m_destination(std::move(destination)) {}
564  bool IsSolvable() const final { return false; }
565 
566  Optional<OutputType> GetOutputType() const override
567  {
568  switch (m_destination.which()) {
569  case 1 /* PKHash */:
570  case 2 /* ScriptHash */: return OutputType::LEGACY;
571  case 3 /* WitnessV0ScriptHash */:
572  case 4 /* WitnessV0KeyHash */:
573  case 5 /* WitnessUnknown */: return OutputType::BECH32;
574  case 0 /* CNoDestination */:
575  default: return nullopt;
576  }
577  }
578  bool IsSingleType() const final { return true; }
579 };
580 
582 class RawDescriptor final : public DescriptorImpl
583 {
584  const CScript m_script;
585 protected:
586  std::string ToStringExtra() const override { return HexStr(m_script); }
587  std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, const CScript*, FlatSigningProvider&) const override { return Vector(m_script); }
588 public:
589  RawDescriptor(CScript script) : DescriptorImpl({}, {}, "raw"), m_script(std::move(script)) {}
590  bool IsSolvable() const final { return false; }
591 
592  Optional<OutputType> GetOutputType() const override
593  {
594  CTxDestination dest;
595  ExtractDestination(m_script, dest);
596  switch (dest.which()) {
597  case 1 /* PKHash */:
598  case 2 /* ScriptHash */: return OutputType::LEGACY;
599  case 3 /* WitnessV0ScriptHash */:
600  case 4 /* WitnessV0KeyHash */:
601  case 5 /* WitnessUnknown */: return OutputType::BECH32;
602  case 0 /* CNoDestination */:
603  default: return nullopt;
604  }
605  }
606  bool IsSingleType() const final { return true; }
607 };
608 
610 class PKDescriptor final : public DescriptorImpl
611 {
612 protected:
613  std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, const CScript*, FlatSigningProvider&) const override { return Vector(GetScriptForRawPubKey(keys[0])); }
614 public:
615  PKDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), {}, "pk") {}
616  bool IsSingleType() const final { return true; }
617 };
618 
620 class PKHDescriptor final : public DescriptorImpl
621 {
622 protected:
623  std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, const CScript*, FlatSigningProvider& out) const override
624  {
625  CKeyID id = keys[0].GetID();
626  out.pubkeys.emplace(id, keys[0]);
628  }
629 public:
630  PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), {}, "pkh") {}
631  Optional<OutputType> GetOutputType() const override { return OutputType::LEGACY; }
632  bool IsSingleType() const final { return true; }
633 };
634 
636 class WPKHDescriptor final : public DescriptorImpl
637 {
638 protected:
639  std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, const CScript*, FlatSigningProvider& out) const override
640  {
641  CKeyID id = keys[0].GetID();
642  out.pubkeys.emplace(id, keys[0]);
644  }
645 public:
646  WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), {}, "wpkh") {}
647  Optional<OutputType> GetOutputType() const override { return OutputType::BECH32; }
648  bool IsSingleType() const final { return true; }
649 };
650 
652 class ComboDescriptor final : public DescriptorImpl
653 {
654 protected:
655  std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, const CScript*, FlatSigningProvider& out) const override
656  {
657  std::vector<CScript> ret;
658  CKeyID id = keys[0].GetID();
659  out.pubkeys.emplace(id, keys[0]);
660  ret.emplace_back(GetScriptForRawPubKey(keys[0])); // P2PK
661  ret.emplace_back(GetScriptForDestination(PKHash(id))); // P2PKH
662  if (keys[0].IsCompressed()) {
664  out.scripts.emplace(CScriptID(p2wpkh), p2wpkh);
665  ret.emplace_back(p2wpkh);
666  ret.emplace_back(GetScriptForDestination(ScriptHash(p2wpkh))); // P2SH-P2WPKH
667  }
668  return ret;
669  }
670 public:
671  ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), {}, "combo") {}
672  bool IsSingleType() const final { return false; }
673 };
674 
676 class MultisigDescriptor final : public DescriptorImpl
677 {
678  const int m_threshold;
679  const bool m_sorted;
680 protected:
681  std::string ToStringExtra() const override { return strprintf("%i", m_threshold); }
682  std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, const CScript*, FlatSigningProvider&) const override {
683  if (m_sorted) {
684  std::vector<CPubKey> sorted_keys(keys);
685  std::sort(sorted_keys.begin(), sorted_keys.end());
686  return Vector(GetScriptForMultisig(m_threshold, sorted_keys));
687  }
688  return Vector(GetScriptForMultisig(m_threshold, keys));
689  }
690 public:
691  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) {}
692  bool IsSingleType() const final { return true; }
693 };
694 
696 class SHDescriptor final : public DescriptorImpl
697 {
698 protected:
699  std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, const CScript* script, FlatSigningProvider&) const override { return Vector(GetScriptForDestination(ScriptHash(*script))); }
700 public:
701  SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc), "sh") {}
702 
703  Optional<OutputType> GetOutputType() const override
704  {
705  assert(m_subdescriptor_arg);
706  if (m_subdescriptor_arg->GetOutputType() == OutputType::BECH32) return OutputType::P2SH_SEGWIT;
707  return OutputType::LEGACY;
708  }
709  bool IsSingleType() const final { return true; }
710 };
711 
713 class WSHDescriptor final : public DescriptorImpl
714 {
715 protected:
716  std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, const CScript* script, FlatSigningProvider&) const override { return Vector(GetScriptForDestination(WitnessV0ScriptHash(*script))); }
717 public:
718  WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc), "wsh") {}
719  Optional<OutputType> GetOutputType() const override { return OutputType::BECH32; }
720  bool IsSingleType() const final { return true; }
721 };
722 
724 // Parser //
726 
727 enum class ParseScriptContext {
728  TOP,
729  P2SH,
730  P2WSH,
731 };
732 
734 NODISCARD bool ParseKeyPath(const std::vector<Span<const char>>& split, KeyPath& out, std::string& error)
735 {
736  for (size_t i = 1; i < split.size(); ++i) {
737  Span<const char> elem = split[i];
738  bool hardened = false;
739  if (elem.size() > 0 && (elem[elem.size() - 1] == '\'' || elem[elem.size() - 1] == 'h')) {
740  elem = elem.first(elem.size() - 1);
741  hardened = true;
742  }
743  uint32_t p;
744  if (!ParseUInt32(std::string(elem.begin(), elem.end()), &p)) {
745  error = strprintf("Key path value '%s' is not a valid uint32", std::string(elem.begin(), elem.end()));
746  return false;
747  } else if (p > 0x7FFFFFFFUL) {
748  error = strprintf("Key path value %u is out of range", p);
749  return false;
750  }
751  out.push_back(p | (((uint32_t)hardened) << 31));
752  }
753  return true;
754 }
755 
757 std::unique_ptr<PubkeyProvider> ParsePubkeyInner(uint32_t key_exp_index, const Span<const char>& sp, bool permit_uncompressed, FlatSigningProvider& out, std::string& error)
758 {
759  using namespace spanparsing;
760 
761  auto split = Split(sp, '/');
762  std::string str(split[0].begin(), split[0].end());
763  if (str.size() == 0) {
764  error = "No key provided";
765  return nullptr;
766  }
767  if (split.size() == 1) {
768  if (IsHex(str)) {
769  std::vector<unsigned char> data = ParseHex(str);
770  CPubKey pubkey(data);
771  if (pubkey.IsFullyValid()) {
772  if (permit_uncompressed || pubkey.IsCompressed()) {
773  return MakeUnique<ConstPubkeyProvider>(key_exp_index, pubkey);
774  } else {
775  error = "Uncompressed keys are not allowed";
776  return nullptr;
777  }
778  }
779  error = strprintf("Pubkey '%s' is invalid", str);
780  return nullptr;
781  }
782  CKey key = DecodeSecret(str);
783  if (key.IsValid()) {
784  if (permit_uncompressed || key.IsCompressed()) {
785  CPubKey pubkey = key.GetPubKey();
786  out.keys.emplace(pubkey.GetID(), key);
787  return MakeUnique<ConstPubkeyProvider>(key_exp_index, pubkey);
788  } else {
789  error = "Uncompressed keys are not allowed";
790  return nullptr;
791  }
792  }
793  }
794  CExtKey extkey = DecodeExtKey(str);
795  CExtPubKey extpubkey = DecodeExtPubKey(str);
796  if (!extkey.key.IsValid() && !extpubkey.pubkey.IsValid()) {
797  error = strprintf("key '%s' is not valid", str);
798  return nullptr;
799  }
800  KeyPath path;
801  DeriveType type = DeriveType::NO;
802  if (split.back() == MakeSpan("*").first(1)) {
803  split.pop_back();
804  type = DeriveType::UNHARDENED;
805  } else if (split.back() == MakeSpan("*'").first(2) || split.back() == MakeSpan("*h").first(2)) {
806  split.pop_back();
807  type = DeriveType::HARDENED;
808  }
809  if (!ParseKeyPath(split, path, error)) return nullptr;
810  if (extkey.key.IsValid()) {
811  extpubkey = extkey.Neuter();
812  out.keys.emplace(extpubkey.pubkey.GetID(), extkey.key);
813  }
814  return MakeUnique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type);
815 }
816 
818 std::unique_ptr<PubkeyProvider> ParsePubkey(uint32_t key_exp_index, const Span<const char>& sp, bool permit_uncompressed, FlatSigningProvider& out, std::string& error)
819 {
820  using namespace spanparsing;
821 
822  auto origin_split = Split(sp, ']');
823  if (origin_split.size() > 2) {
824  error = "Multiple ']' characters found for a single pubkey";
825  return nullptr;
826  }
827  if (origin_split.size() == 1) return ParsePubkeyInner(key_exp_index, origin_split[0], permit_uncompressed, out, error);
828  if (origin_split[0].size() < 1 || origin_split[0][0] != '[') {
829  error = strprintf("Key origin start '[ character expected but not found, got '%c' instead", origin_split[0][0]);
830  return nullptr;
831  }
832  auto slash_split = Split(origin_split[0].subspan(1), '/');
833  if (slash_split[0].size() != 8) {
834  error = strprintf("Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
835  return nullptr;
836  }
837  std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
838  if (!IsHex(fpr_hex)) {
839  error = strprintf("Fingerprint '%s' is not hex", fpr_hex);
840  return nullptr;
841  }
842  auto fpr_bytes = ParseHex(fpr_hex);
843  KeyOriginInfo info;
844  static_assert(sizeof(info.fingerprint) == 4, "Fingerprint must be 4 bytes");
845  assert(fpr_bytes.size() == 4);
846  std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.fingerprint);
847  if (!ParseKeyPath(slash_split, info.path, error)) return nullptr;
848  auto provider = ParsePubkeyInner(key_exp_index, origin_split[1], permit_uncompressed, out, error);
849  if (!provider) return nullptr;
850  return MakeUnique<OriginPubkeyProvider>(key_exp_index, std::move(info), std::move(provider));
851 }
852 
854 std::unique_ptr<DescriptorImpl> ParseScript(uint32_t key_exp_index, Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
855 {
856  using namespace spanparsing;
857 
858  auto expr = Expr(sp);
859  bool sorted_multi = false;
860  if (Func("pk", expr)) {
861  auto pubkey = ParsePubkey(key_exp_index, expr, ctx != ParseScriptContext::P2WSH, out, error);
862  if (!pubkey) return nullptr;
863  return MakeUnique<PKDescriptor>(std::move(pubkey));
864  }
865  if (Func("pkh", expr)) {
866  auto pubkey = ParsePubkey(key_exp_index, expr, ctx != ParseScriptContext::P2WSH, out, error);
867  if (!pubkey) return nullptr;
868  return MakeUnique<PKHDescriptor>(std::move(pubkey));
869  }
870  if (ctx == ParseScriptContext::TOP && Func("combo", expr)) {
871  auto pubkey = ParsePubkey(key_exp_index, expr, true, out, error);
872  if (!pubkey) return nullptr;
873  return MakeUnique<ComboDescriptor>(std::move(pubkey));
874  } else if (ctx != ParseScriptContext::TOP && Func("combo", expr)) {
875  error = "Cannot have combo in non-top level";
876  return nullptr;
877  }
878  if ((sorted_multi = Func("sortedmulti", expr)) || Func("multi", expr)) {
879  auto threshold = Expr(expr);
880  uint32_t thres;
881  std::vector<std::unique_ptr<PubkeyProvider>> providers;
882  if (!ParseUInt32(std::string(threshold.begin(), threshold.end()), &thres)) {
883  error = strprintf("Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
884  return nullptr;
885  }
886  size_t script_size = 0;
887  while (expr.size()) {
888  if (!Const(",", expr)) {
889  error = strprintf("Multi: expected ',', got '%c'", expr[0]);
890  return nullptr;
891  }
892  auto arg = Expr(expr);
893  auto pk = ParsePubkey(key_exp_index, arg, ctx != ParseScriptContext::P2WSH, out, error);
894  if (!pk) return nullptr;
895  script_size += pk->GetSize() + 1;
896  providers.emplace_back(std::move(pk));
897  key_exp_index++;
898  }
899  if (providers.size() < 1 || providers.size() > 16) {
900  error = strprintf("Cannot have %u keys in multisig; must have between 1 and 16 keys, inclusive", providers.size());
901  return nullptr;
902  } else if (thres < 1) {
903  error = strprintf("Multisig threshold cannot be %d, must be at least 1", thres);
904  return nullptr;
905  } else if (thres > providers.size()) {
906  error = strprintf("Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
907  return nullptr;
908  }
909  if (ctx == ParseScriptContext::TOP) {
910  if (providers.size() > 3) {
911  error = strprintf("Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
912  return nullptr;
913  }
914  }
915  if (ctx == ParseScriptContext::P2SH) {
916  if (script_size + 3 > MAX_SCRIPT_ELEMENT_SIZE) {
917  error = strprintf("P2SH script is too large, %d bytes is larger than %d bytes", script_size + 3, MAX_SCRIPT_ELEMENT_SIZE);
918  return nullptr;
919  }
920  }
921  return MakeUnique<MultisigDescriptor>(thres, std::move(providers), sorted_multi);
922  }
923  if (ctx != ParseScriptContext::P2WSH && Func("wpkh", expr)) {
924  auto pubkey = ParsePubkey(key_exp_index, expr, false, out, error);
925  if (!pubkey) return nullptr;
926  return MakeUnique<WPKHDescriptor>(std::move(pubkey));
927  } else if (ctx == ParseScriptContext::P2WSH && Func("wpkh", expr)) {
928  error = "Cannot have wpkh within wsh";
929  return nullptr;
930  }
931  if (ctx == ParseScriptContext::TOP && Func("sh", expr)) {
932  auto desc = ParseScript(key_exp_index, expr, ParseScriptContext::P2SH, out, error);
933  if (!desc || expr.size()) return nullptr;
934  return MakeUnique<SHDescriptor>(std::move(desc));
935  } else if (ctx != ParseScriptContext::TOP && Func("sh", expr)) {
936  error = "Cannot have sh in non-top level";
937  return nullptr;
938  }
939  if (ctx != ParseScriptContext::P2WSH && Func("wsh", expr)) {
940  auto desc = ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH, out, error);
941  if (!desc || expr.size()) return nullptr;
942  return MakeUnique<WSHDescriptor>(std::move(desc));
943  } else if (ctx == ParseScriptContext::P2WSH && Func("wsh", expr)) {
944  error = "Cannot have wsh within wsh";
945  return nullptr;
946  }
947  if (ctx == ParseScriptContext::TOP && Func("addr", expr)) {
948  CTxDestination dest = DecodeDestination(std::string(expr.begin(), expr.end()));
949  if (!IsValidDestination(dest)) {
950  error = "Address is not valid";
951  return nullptr;
952  }
953  return MakeUnique<AddressDescriptor>(std::move(dest));
954  }
955  if (ctx == ParseScriptContext::TOP && Func("raw", expr)) {
956  std::string str(expr.begin(), expr.end());
957  if (!IsHex(str)) {
958  error = "Raw script is not hex";
959  return nullptr;
960  }
961  auto bytes = ParseHex(str);
962  return MakeUnique<RawDescriptor>(CScript(bytes.begin(), bytes.end()));
963  }
964  if (ctx == ParseScriptContext::P2SH) {
965  error = "A function is needed within P2SH";
966  return nullptr;
967  } else if (ctx == ParseScriptContext::P2WSH) {
968  error = "A function is needed within P2WSH";
969  return nullptr;
970  }
971  error = strprintf("%s is not a valid descriptor function", std::string(expr.begin(), expr.end()));
972  return nullptr;
973 }
974 
975 std::unique_ptr<PubkeyProvider> InferPubkey(const CPubKey& pubkey, ParseScriptContext, const SigningProvider& provider)
976 {
977  std::unique_ptr<PubkeyProvider> key_provider = MakeUnique<ConstPubkeyProvider>(0, pubkey);
978  KeyOriginInfo info;
979  if (provider.GetKeyOrigin(pubkey.GetID(), info)) {
980  return MakeUnique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider));
981  }
982  return key_provider;
983 }
984 
985 std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptContext ctx, const SigningProvider& provider)
986 {
987  std::vector<std::vector<unsigned char>> data;
988  TxoutType txntype = Solver(script, data);
989 
990  if (txntype == TxoutType::PUBKEY) {
991  CPubKey pubkey(data[0].begin(), data[0].end());
992  if (pubkey.IsValid()) {
993  return MakeUnique<PKDescriptor>(InferPubkey(pubkey, ctx, provider));
994  }
995  }
996  if (txntype == TxoutType::PUBKEYHASH) {
997  uint160 hash(data[0]);
998  CKeyID keyid(hash);
999  CPubKey pubkey;
1000  if (provider.GetPubKey(keyid, pubkey)) {
1001  return MakeUnique<PKHDescriptor>(InferPubkey(pubkey, ctx, provider));
1002  }
1003  }
1004  if (txntype == TxoutType::WITNESS_V0_KEYHASH && ctx != ParseScriptContext::P2WSH) {
1005  uint160 hash(data[0]);
1006  CKeyID keyid(hash);
1007  CPubKey pubkey;
1008  if (provider.GetPubKey(keyid, pubkey)) {
1009  return MakeUnique<WPKHDescriptor>(InferPubkey(pubkey, ctx, provider));
1010  }
1011  }
1012  if (txntype == TxoutType::MULTISIG) {
1013  std::vector<std::unique_ptr<PubkeyProvider>> providers;
1014  for (size_t i = 1; i + 1 < data.size(); ++i) {
1015  CPubKey pubkey(data[i].begin(), data[i].end());
1016  providers.push_back(InferPubkey(pubkey, ctx, provider));
1017  }
1018  return MakeUnique<MultisigDescriptor>((int)data[0][0], std::move(providers));
1019  }
1020  if (txntype == TxoutType::SCRIPTHASH && ctx == ParseScriptContext::TOP) {
1021  uint160 hash(data[0]);
1022  CScriptID scriptid(hash);
1023  CScript subscript;
1024  if (provider.GetCScript(scriptid, subscript)) {
1025  auto sub = InferScript(subscript, ParseScriptContext::P2SH, provider);
1026  if (sub) return MakeUnique<SHDescriptor>(std::move(sub));
1027  }
1028  }
1029  if (txntype == TxoutType::WITNESS_V0_SCRIPTHASH && ctx != ParseScriptContext::P2WSH) {
1030  CScriptID scriptid;
1031  CRIPEMD160().Write(data[0].data(), data[0].size()).Finalize(scriptid.begin());
1032  CScript subscript;
1033  if (provider.GetCScript(scriptid, subscript)) {
1034  auto sub = InferScript(subscript, ParseScriptContext::P2WSH, provider);
1035  if (sub) return MakeUnique<WSHDescriptor>(std::move(sub));
1036  }
1037  }
1038 
1039  CTxDestination dest;
1040  if (ExtractDestination(script, dest)) {
1041  if (GetScriptForDestination(dest) == script) {
1042  return MakeUnique<AddressDescriptor>(std::move(dest));
1043  }
1044  }
1045 
1046  return MakeUnique<RawDescriptor>(script);
1047 }
1048 
1049 
1050 } // namespace
1051 
1053 bool CheckChecksum(Span<const char>& sp, bool require_checksum, std::string& error, std::string* out_checksum = nullptr)
1054 {
1055  using namespace spanparsing;
1056 
1057  auto check_split = Split(sp, '#');
1058  if (check_split.size() > 2) {
1059  error = "Multiple '#' symbols";
1060  return false;
1061  }
1062  if (check_split.size() == 1 && require_checksum){
1063  error = "Missing checksum";
1064  return false;
1065  }
1066  if (check_split.size() == 2) {
1067  if (check_split[1].size() != 8) {
1068  error = strprintf("Expected 8 character checksum, not %u characters", check_split[1].size());
1069  return false;
1070  }
1071  }
1072  auto checksum = DescriptorChecksum(check_split[0]);
1073  if (checksum.empty()) {
1074  error = "Invalid characters in payload";
1075  return false;
1076  }
1077  if (check_split.size() == 2) {
1078  if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
1079  error = strprintf("Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
1080  return false;
1081  }
1082  }
1083  if (out_checksum) *out_checksum = std::move(checksum);
1084  sp = check_split[0];
1085  return true;
1086 }
1087 
1088 std::unique_ptr<Descriptor> Parse(const std::string& descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum)
1089 {
1090  Span<const char> sp{descriptor};
1091  if (!CheckChecksum(sp, require_checksum, error)) return nullptr;
1092  auto ret = ParseScript(0, sp, ParseScriptContext::TOP, out, error);
1093  if (sp.size() == 0 && ret) return std::unique_ptr<Descriptor>(std::move(ret));
1094  return nullptr;
1095 }
1096 
1097 std::string GetDescriptorChecksum(const std::string& descriptor)
1098 {
1099  std::string ret;
1100  std::string error;
1101  Span<const char> sp{descriptor};
1102  if (!CheckChecksum(sp, false, error, &ret)) return "";
1103  return ret;
1104 }
1105 
1106 std::unique_ptr<Descriptor> InferDescriptor(const CScript& script, const SigningProvider& provider)
1107 {
1108  return InferScript(script, ParseScriptContext::TOP, provider);
1109 }
1110 
1111 void DescriptorCache::CacheParentExtPubKey(uint32_t key_exp_pos, const CExtPubKey& xpub)
1112 {
1113  m_parent_xpubs[key_exp_pos] = xpub;
1114 }
1115 
1116 void DescriptorCache::CacheDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, const CExtPubKey& xpub)
1117 {
1118  auto& xpubs = m_derived_xpubs[key_exp_pos];
1119  xpubs[der_index] = xpub;
1120 }
1121 
1122 bool DescriptorCache::GetCachedParentExtPubKey(uint32_t key_exp_pos, CExtPubKey& xpub) const
1123 {
1124  const auto& it = m_parent_xpubs.find(key_exp_pos);
1125  if (it == m_parent_xpubs.end()) return false;
1126  xpub = it->second;
1127  return true;
1128 }
1129 
1130 bool DescriptorCache::GetCachedDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, CExtPubKey& xpub) const
1131 {
1132  const auto& key_exp_it = m_derived_xpubs.find(key_exp_pos);
1133  if (key_exp_it == m_derived_xpubs.end()) return false;
1134  const auto& der_it = key_exp_it->second.find(der_index);
1135  if (der_it == key_exp_it->second.end()) return false;
1136  xpub = der_it->second;
1137  return true;
1138 }
1139 
1141 {
1142  return m_parent_xpubs;
1143 }
1144 
1145 const std::unordered_map<uint32_t, ExtPubKeyMap> DescriptorCache::GetCachedDerivedExtPubKeys() const
1146 {
1147  return m_derived_xpubs;
1148 }
Top-level scriptPubKey.
CONSTEXPR_IF_NOT_DEBUG Span< C > first(std::size_t count) const noexcept
Definition: span.h:169
unsigned char * begin()
Definition: standard.h:33
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.
unsigned char fingerprint[4]
First 32 bits of the Hash160 of the public key at the root of the path.
Definition: keyorigin.h:13
const std::unordered_map< uint32_t, ExtPubKeyMap > GetCachedDerivedExtPubKeys() const
Retrieve all cached derived xpubs.
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
Definition: standard.cpp:174
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:142
CKey key
Definition: key.h:149
bool Derive(CExtKey &out, unsigned int nChild) const
Definition: key.cpp:293
DeriveType
Definition: descriptor.cpp:252
#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: 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:328
constexpr std::size_t size() const noexcept
Definition: span.h:153
unsigned char vchFingerprint[4]
Definition: key.h:146
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
Definition: standard.cpp:300
std::map< CKeyID, std::pair< CPubKey, KeyOriginInfo > > origins
std::string FormatHDKeypath(const std::vector< uint32_t > &path)
Definition: bip32.cpp:53
static auto & nullopt
Substitute for C++17 std::nullopt.
Definition: optional.h:24
bool GetCachedParentExtPubKey(uint32_t key_exp_pos, CExtPubKey &xpub) const
Retrieve a cached parent xpub.
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
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:158
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.
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h:69
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:41
unsigned char nDepth
Definition: key.h:145
TxoutType
Definition: standard.h:119
const SigningProvider & DUMMY_SIGNING_PROVIDER
static secp256k1_context * ctx
Definition: tests.c:36
bool IsValid() const
Definition: pubkey.h:174
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:727
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:295
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:141
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
std::unordered_map< uint32_t, CExtPubKey > ExtPubKeyMap
Definition: descriptor.h:16
Cache for single descriptor&#39;s derived extended pubkeys.
Definition: descriptor.h:19
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
void CacheParentExtPubKey(uint32_t key_exp_pos, const CExtPubKey &xpub)
Cache a parent xpub.
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:20
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char >> &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
Definition: standard.cpp:109
std::string HexStr(const T itbegin, const T itend)
Definition: strencodings.h:123
160-bit opaque blob.
Definition: uint256.h:109
A reference to a CScript: the Hash160 of its serialization (see script.h)
Definition: standard.h:85
std::string EncodeDestination(const CTxDestination &dest)
Definition: key_io.cpp:210
CPubKey pubkey
Definition: pubkey.h:214
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
Definition: standard.cpp:305
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:82
boost::optional< T > Optional
Substitute for C++17 std::optional.
Definition: optional.h:14
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:209
CScript ParseScript(const std::string &s)
Definition: core_read.cpp:24
const ExtPubKeyMap GetCachedParentExtPubKeys() const
Retrieve all cached parent xpubs.
auto it
Definition: validation.cpp:384
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
void CacheDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, const CExtPubKey &xpub)
Cache an xpub derived at an index.
std::string EncodeExtKey(const CExtKey &key)
Definition: key_io.cpp:199
Interface for parsed descriptor objects.
Definition: descriptor.h:77
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 GetCachedDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, CExtPubKey &xpub) const
Retrieve a cached xpub derived at an index.
Span< A > constexpr MakeSpan(A(&a)[N])
MakeSpan for arrays:
Definition: span.h:192
bool IsCompressed() const
Check whether this is a compressed public key.
Definition: pubkey.h:183