90 uint64_t
PolyMod(uint64_t c,
int val)
93 c = ((c & 0x7ffffffff) << 5) ^ val;
94 if (c0 & 1) c ^= 0xf5dee51989;
95 if (c0 & 2) c ^= 0xa9fdca3312;
96 if (c0 & 4) c ^= 0x1bab10e32d;
97 if (c0 & 8) c ^= 0x3706b1677a;
98 if (c0 & 16) c ^= 0x644d626ffd;
117 static std::string INPUT_CHARSET =
118 "0123456789()[],'/*abcdefgh@:$%{}"
119 "IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~"
120 "ijklmnopqrstuvwxyzABCDEFGH`#\"\\ ";
123 static std::string CHECKSUM_CHARSET =
"qpzry9x8gf2tvdw0s3jn54khce6mua7l";
128 for (
auto ch : span) {
129 auto pos = INPUT_CHARSET.find(ch);
130 if (pos == std::string::npos)
return "";
132 cls = cls * 3 + (pos >> 5);
133 if (++clscount == 3) {
140 if (clscount > 0) c =
PolyMod(c, cls);
141 for (
int j = 0; j < 8; ++j) c =
PolyMod(c, 0);
144 std::string
ret(8,
' ');
145 for (
int j = 0; j < 8; ++j)
ret[j] = CHECKSUM_CHARSET[(c >> (5 * (7 - j))) & 31];
149 std::string AddChecksum(
const std::string& str) {
return str +
"#" + DescriptorChecksum(str); }
155 typedef std::vector<uint32_t> KeyPath;
158 struct PubkeyProvider
163 uint32_t m_expr_index;
166 explicit PubkeyProvider(uint32_t exp_index) : m_expr_index(exp_index) {}
168 virtual ~PubkeyProvider() =
default;
173 bool operator<(PubkeyProvider& other)
const {
179 other.GetPubKey(0, dummy, b, dummy_info);
192 virtual bool IsRange()
const = 0;
195 virtual size_t GetSize()
const = 0;
197 enum class StringType {
203 virtual std::string
ToString(StringType type=StringType::PUBLIC)
const = 0;
217 class OriginPubkeyProvider final :
public PubkeyProvider
220 std::unique_ptr<PubkeyProvider> m_provider;
223 std::string OriginString(StringType type,
bool normalized=
false)
const
226 bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
231 OriginPubkeyProvider(uint32_t exp_index,
KeyOriginInfo info, std::unique_ptr<PubkeyProvider> provider,
bool apostrophe) : PubkeyProvider(exp_index), m_origin(
std::move(info)), m_provider(
std::move(provider)), m_apostrophe(apostrophe) {}
234 if (!m_provider->GetPubKey(pos, arg, key, info, read_cache, write_cache))
return false;
235 std::copy(std::begin(m_origin.fingerprint), std::end(m_origin.fingerprint), info.
fingerprint);
236 info.
path.insert(info.
path.begin(), m_origin.path.begin(), m_origin.path.end());
239 bool IsRange()
const override {
return m_provider->IsRange(); }
240 size_t GetSize()
const override {
return m_provider->GetSize(); }
241 std::string
ToString(StringType type)
const override {
return "[" + OriginString(type) +
"]" + m_provider->ToString(type); }
245 if (!m_provider->ToPrivateString(arg, sub))
return false;
246 ret =
"[" + OriginString(StringType::PUBLIC) +
"]" + std::move(sub);
252 if (!m_provider->ToNormalizedString(arg, sub, cache))
return false;
258 ret =
"[" + OriginString(StringType::PUBLIC,
true) + std::move(sub);
260 ret =
"[" + OriginString(StringType::PUBLIC,
true) +
"]" + std::move(sub);
266 return m_provider->GetPrivKey(pos, arg, key);
271 class ConstPubkeyProvider final :
public PubkeyProvider
277 ConstPubkeyProvider(uint32_t exp_index,
const CPubKey& pubkey,
bool xonly) : PubkeyProvider(exp_index), m_pubkey(pubkey), m_xonly(xonly) {}
282 CKeyID keyid = m_pubkey.GetID();
286 bool IsRange()
const override {
return false; }
287 size_t GetSize()
const override {
return m_pubkey.size(); }
288 std::string
ToString(StringType type)
const override {
return m_xonly ?
HexStr(m_pubkey).substr(2) :
HexStr(m_pubkey); }
293 for (
const auto& keyid :
XOnlyPubKey(m_pubkey).GetKeyIDs()) {
298 arg.
GetKey(m_pubkey.GetID(), key);
300 if (!key.
IsValid())
return false;
311 return arg.
GetKey(m_pubkey.GetID(), key);
315 enum class DeriveType {
322 class BIP32PubkeyProvider final :
public PubkeyProvider
334 if (!arg.
GetKey(m_root_extkey.pubkey.GetID(), key))
return false;
335 ret.nDepth = m_root_extkey.nDepth;
336 std::copy(m_root_extkey.vchFingerprint, m_root_extkey.vchFingerprint +
sizeof(
ret.vchFingerprint),
ret.vchFingerprint);
337 ret.nChild = m_root_extkey.nChild;
338 ret.chaincode = m_root_extkey.chaincode;
346 if (!GetExtKey(arg, xprv))
return false;
347 for (
auto entry : m_path) {
348 if (!xprv.
Derive(xprv, entry))
return false;
350 last_hardened = xprv;
356 bool IsHardened()
const
358 if (m_derive == DeriveType::HARDENED)
return true;
359 for (
auto entry : m_path) {
360 if (entry >> 31)
return true;
366 BIP32PubkeyProvider(uint32_t exp_index,
const CExtPubKey& extkey, KeyPath path, DeriveType derive,
bool apostrophe) : PubkeyProvider(exp_index), m_root_extkey(extkey), m_path(
std::move(path)), m_derive(derive), m_apostrophe(apostrophe) {}
367 bool IsRange()
const override {
return m_derive != DeriveType::NO; }
368 size_t GetSize()
const override {
return 33; }
373 CKeyID keyid = m_root_extkey.pubkey.GetID();
375 parent_info.
path = m_path;
379 if (m_derive == DeriveType::UNHARDENED) final_info_out_tmp.
path.push_back((uint32_t)pos);
380 if (m_derive == DeriveType::HARDENED) final_info_out_tmp.
path.push_back(((uint32_t)pos) | 0x80000000L);
388 if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
389 if (m_derive == DeriveType::HARDENED)
return false;
391 if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey))
return false;
392 final_extkey = parent_extkey;
393 if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.
Derive(final_extkey, pos);
395 }
else if (IsHardened()) {
398 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return false;
399 parent_extkey = xprv.
Neuter();
400 if (m_derive == DeriveType::UNHARDENED) der = xprv.
Derive(xprv, pos);
401 if (m_derive == DeriveType::HARDENED) der = xprv.
Derive(xprv, pos | 0x80000000UL);
402 final_extkey = xprv.
Neuter();
404 last_hardened_extkey = lh_xprv.
Neuter();
407 for (
auto entry : m_path) {
408 if (!parent_extkey.
Derive(parent_extkey, entry))
return false;
410 final_extkey = parent_extkey;
411 if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.
Derive(final_extkey, pos);
412 assert(m_derive != DeriveType::HARDENED);
414 if (!der)
return false;
416 final_info_out = final_info_out_tmp;
417 key_out = final_extkey.
pubkey;
421 if (m_derive != DeriveType::HARDENED) {
422 write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
425 write_cache->CacheLastHardenedExtPubKey(m_expr_index, last_hardened_extkey);
427 }
else if (final_info_out.
path.size() > 0) {
428 write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey);
434 std::string
ToString(StringType type,
bool normalized)
const
437 const bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
441 if (m_derive == DeriveType::HARDENED)
ret += use_apostrophe ?
'\'' :
'h';
445 std::string
ToString(StringType type=StringType::PUBLIC)
const override
452 if (!GetExtKey(arg, key))
return false;
456 if (m_derive == DeriveType::HARDENED)
out += m_apostrophe ?
'\'' :
'h';
462 if (m_derive == DeriveType::HARDENED) {
468 int i = (int)m_path.size() - 1;
469 for (; i >= 0; --i) {
470 if (m_path.at(i) >> 31) {
482 for (;
k <= i; ++
k) {
484 origin.
path.push_back(m_path.at(
k));
488 for (;
k < (int)m_path.size(); ++
k) {
489 end_path.push_back(m_path.at(
k));
492 CKeyID id = m_root_extkey.pubkey.GetID();
493 std::copy(
id.begin(),
id.begin() + 4, origin.
fingerprint);
498 if (cache !=
nullptr) {
504 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return false;
514 assert(m_derive == DeriveType::UNHARDENED);
522 if (!GetDerivedExtKey(arg, extkey, dummy))
return false;
523 if (m_derive == DeriveType::UNHARDENED && !extkey.
Derive(extkey, pos))
return false;
524 if (m_derive == DeriveType::HARDENED && !extkey.
Derive(extkey, pos | 0x80000000UL))
return false;
535 const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args;
537 const std::string m_name;
543 const std::vector<std::unique_ptr<DescriptorImpl>> m_subdescriptor_args;
546 virtual std::string ToStringExtra()
const {
return ""; }
561 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys,
const std::string&
name) : m_pubkey_args(
std::move(pubkeys)), m_name(
name), m_subdescriptor_args() {}
562 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_args(
Vector(
std::move(script))) {}
563 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, std::vector<std::unique_ptr<DescriptorImpl>> scripts,
const std::string&
name) : m_pubkey_args(
std::move(pubkeys)), m_name(
name), m_subdescriptor_args(
std::move(scripts)) {}
565 enum class StringType
575 for (
const auto& arg : m_subdescriptor_args) {
576 if (!arg->IsSolvable())
return false;
583 for (
const auto& pubkey : m_pubkey_args) {
584 if (pubkey->IsRange())
return true;
586 for (
const auto& arg : m_subdescriptor_args) {
587 if (arg->IsRange())
return true;
595 for (
const auto& scriptarg : m_subdescriptor_args) {
596 if (pos++)
ret +=
",";
598 if (!scriptarg->ToStringHelper(arg, tmp, type, cache))
return false;
606 std::string extra = ToStringExtra();
607 size_t pos = extra.size() > 0 ? 1 : 0;
608 std::string
ret = m_name +
"(" + extra;
609 for (
const auto& pubkey : m_pubkey_args) {
610 if (pos++)
ret +=
",";
613 case StringType::NORMALIZED:
614 if (!pubkey->ToNormalizedString(*arg, tmp, cache))
return false;
616 case StringType::PRIVATE:
617 if (!pubkey->ToPrivateString(*arg, tmp))
return false;
619 case StringType::PUBLIC:
620 tmp = pubkey->ToString();
622 case StringType::COMPAT:
623 tmp = pubkey->ToString(PubkeyProvider::StringType::COMPAT);
628 std::string subscript;
629 if (!ToStringSubScriptHelper(arg, subscript, type, cache))
return false;
630 if (pos && subscript.size())
ret +=
',';
631 out = std::move(
ret) + std::move(subscript) +
")";
635 std::string
ToString(
bool compat_format)
const final
638 ToStringHelper(
nullptr,
ret, compat_format ? StringType::COMPAT : StringType::PUBLIC);
639 return AddChecksum(
ret);
644 bool ret = ToStringHelper(&arg,
out, StringType::PRIVATE);
651 bool ret = ToStringHelper(&arg,
out, StringType::NORMALIZED, cache);
658 std::vector<std::pair<CPubKey, KeyOriginInfo>> entries;
659 entries.reserve(m_pubkey_args.size());
662 for (
const auto& p : m_pubkey_args) {
663 entries.emplace_back();
664 if (!p->GetPubKey(pos, arg, entries.back().first, entries.back().second, read_cache, write_cache))
return false;
666 std::vector<CScript> subscripts;
668 for (
const auto& subarg : m_subdescriptor_args) {
669 std::vector<CScript> outscripts;
670 if (!subarg->ExpandHelper(pos, arg, read_cache, outscripts, subprovider, write_cache))
return false;
671 assert(outscripts.size() == 1);
672 subscripts.emplace_back(std::move(outscripts[0]));
674 out.Merge(std::move(subprovider));
676 std::vector<CPubKey> pubkeys;
677 pubkeys.reserve(entries.size());
678 for (
auto& entry : entries) {
679 pubkeys.push_back(entry.first);
680 out.origins.emplace(entry.first.GetID(), std::make_pair<CPubKey, KeyOriginInfo>(
CPubKey(entry.first), std::move(entry.second)));
683 output_scripts = MakeScripts(pubkeys,
Span{subscripts},
out);
689 return ExpandHelper(pos, provider,
nullptr, output_scripts,
out, write_cache);
699 for (
const auto& p : m_pubkey_args) {
701 if (!p->GetPrivKey(pos, provider, key))
continue;
704 for (
const auto& arg : m_subdescriptor_args) {
705 arg->ExpandPrivate(pos, provider,
out);
709 std::optional<OutputType>
GetOutputType()
const override {
return std::nullopt; }
711 std::optional<int64_t>
ScriptSize()
const override {
return {}; }
718 virtual std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const {
return {}; }
726 class AddressDescriptor final :
public DescriptorImpl
730 std::string ToStringExtra()
const override {
return EncodeDestination(m_destination); }
733 AddressDescriptor(
CTxDestination destination) : DescriptorImpl({},
"addr"), m_destination(std::move(destination)) {}
734 bool IsSolvable() const final {
return false; }
740 bool IsSingleType() const final {
return true; }
741 bool ToPrivateString(
const SigningProvider& arg, std::string&
out)
const final {
return false; }
747 class RawDescriptor final :
public DescriptorImpl
751 std::string ToStringExtra()
const override {
return HexStr(m_script); }
754 RawDescriptor(
CScript script) : DescriptorImpl({},
"raw"), m_script(std::move(script)) {}
755 bool IsSolvable() const final {
return false; }
763 bool IsSingleType() const final {
return true; }
764 bool ToPrivateString(
const SigningProvider& arg, std::string&
out)
const final {
return false; }
766 std::optional<int64_t> ScriptSize()
const override {
return m_script.size(); }
770 class PKDescriptor final :
public DescriptorImpl
779 return Vector(std::move(script));
785 PKDescriptor(std::unique_ptr<PubkeyProvider> prov,
bool xonly =
false) : DescriptorImpl(
Vector(
std::move(prov)),
"pk"), m_xonly(xonly) {}
786 bool IsSingleType() const final {
return true; }
788 std::optional<int64_t> ScriptSize()
const override {
789 return 1 + (m_xonly ? 32 : m_pubkey_args[0]->GetSize()) + 1;
792 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
793 const auto ecdsa_sig_size = use_max_sig ? 72 : 71;
794 return 1 + (m_xonly ? 65 : ecdsa_sig_size);
797 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
801 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1; }
805 class PKHDescriptor final :
public DescriptorImpl
810 CKeyID id = keys[0].GetID();
811 out.pubkeys.emplace(
id, keys[0]);
815 PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"pkh") {}
817 bool IsSingleType() const final {
return true; }
819 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 1 + 20 + 1 + 1; }
821 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
822 const auto sig_size = use_max_sig ? 72 : 71;
823 return 1 +
sig_size + 1 + m_pubkey_args[0]->GetSize();
826 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
830 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
834 class WPKHDescriptor final :
public DescriptorImpl
839 CKeyID id = keys[0].GetID();
840 out.pubkeys.emplace(
id, keys[0]);
844 WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"wpkh") {}
846 bool IsSingleType() const final {
return true; }
848 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20; }
850 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
851 const auto sig_size = use_max_sig ? 72 : 71;
855 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
856 return MaxSatSize(use_max_sig);
859 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
863 class ComboDescriptor final :
public DescriptorImpl
868 std::vector<CScript>
ret;
869 CKeyID id = keys[0].GetID();
870 out.pubkeys.emplace(
id, keys[0]);
873 if (keys[0].IsCompressed()) {
876 ret.emplace_back(p2wpkh);
882 ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"combo") {}
883 bool IsSingleType() const final {
return false; }
887 class MultisigDescriptor final :
public DescriptorImpl
889 const int m_threshold;
892 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
895 std::vector<CPubKey> sorted_keys(keys);
896 std::sort(sorted_keys.begin(), sorted_keys.end());
902 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) {}
903 bool IsSingleType() const final {
return true; }
905 std::optional<int64_t> ScriptSize()
const override {
906 const auto n_keys = m_pubkey_args.size();
907 auto op = [](int64_t acc,
const std::unique_ptr<PubkeyProvider>&
pk) {
return acc + 1 +
pk->GetSize();};
908 const auto pubkeys_size{std::accumulate(m_pubkey_args.begin(), m_pubkey_args.end(), int64_t{0}, op)};
912 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
913 const auto sig_size = use_max_sig ? 72 : 71;
914 return (1 + (1 +
sig_size) * m_threshold);
917 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
921 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1 + m_threshold; }
925 class MultiADescriptor final :
public DescriptorImpl
927 const int m_threshold;
930 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
933 std::vector<XOnlyPubKey> xkeys;
934 xkeys.reserve(keys.size());
935 for (
const auto& key : keys) xkeys.emplace_back(key);
936 if (m_sorted) std::sort(xkeys.begin(), xkeys.end());
938 for (
size_t i = 1; i < keys.size(); ++i) {
945 MultiADescriptor(
int threshold, std::vector<std::unique_ptr<PubkeyProvider>> providers,
bool sorted =
false) : DescriptorImpl(
std::move(providers), sorted ?
"sortedmulti_a" :
"multi_a"), m_threshold(threshold), m_sorted(sorted) {}
946 bool IsSingleType() const final {
return true; }
948 std::optional<int64_t> ScriptSize()
const override {
949 const auto n_keys = m_pubkey_args.size();
953 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
954 return (1 + 65) * m_threshold + (m_pubkey_args.size() - m_threshold);
957 std::optional<int64_t> MaxSatisfactionElems()
const override {
return m_pubkey_args.size(); }
961 class SHDescriptor final :
public DescriptorImpl
967 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
974 SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"sh") {}
978 assert(m_subdescriptor_args.size() == 1);
982 bool IsSingleType() const final {
return true; }
984 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20 + 1; }
986 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
987 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
988 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
992 if (
IsSegwit())
return subscript_weight + *sat_size;
999 std::optional<int64_t> MaxSatisfactionElems()
const override {
1000 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1006 class WSHDescriptor final :
public DescriptorImpl
1012 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1016 WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"wsh") {}
1018 bool IsSingleType() const final {
return true; }
1020 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1022 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1023 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1024 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1031 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1032 return MaxSatSize(use_max_sig);
1035 std::optional<int64_t> MaxSatisfactionElems()
const override {
1036 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1042 class TRDescriptor final :
public DescriptorImpl
1044 std::vector<int> m_depths;
1050 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1054 assert(keys.size() == 1);
1056 if (!xpk.IsFullyValid())
return {};
1059 out.tr_trees[output] = builder;
1060 out.pubkeys.emplace(keys[0].GetID(), keys[0]);
1065 if (m_depths.empty())
return true;
1066 std::vector<bool> path;
1067 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1068 if (pos)
ret +=
',';
1069 while ((
int)path.size() <= m_depths[pos]) {
1070 if (path.size())
ret +=
'{';
1071 path.push_back(
false);
1074 if (!m_subdescriptor_args[pos]->ToStringHelper(arg, tmp, type, cache))
return false;
1076 while (!path.empty() && path.back()) {
1077 if (path.size() > 1)
ret +=
'}';
1080 if (!path.empty()) path.back() =
true;
1085 TRDescriptor(std::unique_ptr<PubkeyProvider> internal_key, std::vector<std::unique_ptr<DescriptorImpl>> descs, std::vector<int> depths) :
1086 DescriptorImpl(
Vector(
std::move(internal_key)),
std::move(descs),
"tr"), m_depths(
std::move(depths))
1088 assert(m_subdescriptor_args.size() == m_depths.size());
1091 bool IsSingleType() const final {
return true; }
1093 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1095 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1100 std::optional<int64_t> MaxSatisfactionElems()
const override {
1116 const std::vector<CPubKey>& m_keys;
1123 uint160 GetHash160(uint32_t key)
const {
1127 return m_keys[key].GetID();
1133 std::vector<unsigned char> ToPKBytes(uint32_t key)
const {
1136 return {m_keys[key].begin(), m_keys[key].end()};
1139 return {xonly_pubkey.
begin(), xonly_pubkey.end()};
1142 std::vector<unsigned char> ToPKHBytes(uint32_t key)
const {
1143 auto id = GetHash160(key);
1144 return {
id.begin(),
id.end()};
1155 const std::vector<std::unique_ptr<PubkeyProvider>>& m_pubkeys;
1161 : m_arg(arg), m_pubkeys(pubkeys), m_private(priv) {}
1163 std::optional<std::string>
ToString(uint32_t key)
const
1167 if (!m_pubkeys[key]->ToPrivateString(*m_arg,
ret))
return {};
1169 ret = m_pubkeys[key]->ToString();
1175 class MiniscriptDescriptor final :
public DescriptorImpl
1181 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys,
Span<const CScript> scripts,
1184 const auto script_ctx{
m_node->GetMsCtx()};
1185 for (
const auto& key : keys) {
1189 provider.
pubkeys.emplace(key.GetID(), key);
1192 return Vector(
m_node->ToScript(ScriptMaker(keys, script_ctx)));
1199 bool ToStringHelper(
const SigningProvider* arg, std::string&
out,
const StringType type,
1202 if (
const auto res =
m_node->ToString(StringMaker(arg, m_pubkey_args, type == StringType::PRIVATE))) {
1209 bool IsSolvable()
const override {
return true; }
1210 bool IsSingleType() const final {
return true; }
1212 std::optional<int64_t> ScriptSize()
const override {
return m_node->ScriptSize(); }
1214 std::optional<int64_t> MaxSatSize(
bool)
const override {
1216 return m_node->GetWitnessSize();
1219 std::optional<int64_t> MaxSatisfactionElems()
const override {
1220 return m_node->GetStackSize();
1225 class RawTRDescriptor final :
public DescriptorImpl
1230 assert(keys.size() == 1);
1232 if (!xpk.IsFullyValid())
return {};
1237 RawTRDescriptor(std::unique_ptr<PubkeyProvider> output_key) : DescriptorImpl(
Vector(
std::move(output_key)),
"rawtr") {}
1239 bool IsSingleType() const final {
return true; }
1241 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1243 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1248 std::optional<int64_t> MaxSatisfactionElems()
const override {
1258 enum class ParseScriptContext {
1275 [[nodiscard]]
bool ParseKeyPath(
const std::vector<
Span<const char>>& split, KeyPath&
out,
bool& apostrophe, std::string&
error)
1277 for (
size_t i = 1; i < split.size(); ++i) {
1279 bool hardened =
false;
1280 if (elem.
size() > 0) {
1281 const char last = elem[elem.
size() - 1];
1282 if (last ==
'\'' || last ==
'h') {
1285 apostrophe = last ==
'\'';
1292 }
else if (p > 0x7FFFFFFFUL) {
1296 out.push_back(p | (((uint32_t)hardened) << 31));
1306 bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
1307 auto split =
Split(sp,
'/');
1308 std::string str(split[0].begin(), split[0].end());
1309 if (str.size() == 0) {
1310 error =
"No key provided";
1313 if (split.size() == 1) {
1315 std::vector<unsigned char> data =
ParseHex(str);
1317 if (pubkey.IsValid() && !pubkey.IsValidNonHybrid()) {
1318 error =
"Hybrid public keys are not allowed";
1321 if (pubkey.IsFullyValid()) {
1322 if (permit_uncompressed || pubkey.IsCompressed()) {
1323 return std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
false);
1325 error =
"Uncompressed keys are not allowed";
1328 }
else if (data.size() == 32 && ctx == ParseScriptContext::P2TR) {
1329 unsigned char fullkey[33] = {0x02};
1330 std::copy(data.begin(), data.end(), fullkey + 1);
1331 pubkey.Set(std::begin(fullkey), std::end(fullkey));
1332 if (pubkey.IsFullyValid()) {
1333 return std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
true);
1343 out.keys.emplace(pubkey.
GetID(), key);
1344 return std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, ctx == ParseScriptContext::P2TR);
1346 error =
"Uncompressed keys are not allowed";
1358 DeriveType type = DeriveType::NO;
1359 if (split.back() ==
Span{
"*"}.
first(1)) {
1361 type = DeriveType::UNHARDENED;
1362 }
else if (split.back() ==
Span{
"*'"}.
first(2) || split.back() ==
Span{
"*h"}.
first(2)) {
1363 apostrophe = split.back() ==
Span{
"*'"}.
first(2);
1365 type = DeriveType::HARDENED;
1367 if (!ParseKeyPath(split, path, apostrophe,
error))
return nullptr;
1369 extpubkey = extkey.
Neuter();
1372 return std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type, apostrophe);
1380 auto origin_split =
Split(sp,
']');
1381 if (origin_split.size() > 2) {
1382 error =
"Multiple ']' characters found for a single pubkey";
1386 bool apostrophe =
false;
1387 if (origin_split.size() == 1) {
1388 return ParsePubkeyInner(key_exp_index, origin_split[0], ctx,
out, apostrophe,
error);
1390 if (origin_split[0].empty() || origin_split[0][0] !=
'[') {
1391 error =
strprintf(
"Key origin start '[ character expected but not found, got '%c' instead",
1392 origin_split[0].empty() ?
']' : origin_split[0][0]);
1395 auto slash_split =
Split(origin_split[0].subspan(1),
'/');
1396 if (slash_split[0].size() != 8) {
1397 error =
strprintf(
"Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
1400 std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
1401 if (!
IsHex(fpr_hex)) {
1405 auto fpr_bytes =
ParseHex(fpr_hex);
1407 static_assert(
sizeof(info.
fingerprint) == 4,
"Fingerprint must be 4 bytes");
1408 assert(fpr_bytes.size() == 4);
1409 std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.
fingerprint);
1410 if (!ParseKeyPath(slash_split, info.
path, apostrophe,
error))
return nullptr;
1411 auto provider = ParsePubkeyInner(key_exp_index, origin_split[1], ctx,
out, apostrophe,
error);
1412 if (!provider)
return nullptr;
1413 return std::make_unique<OriginPubkeyProvider>(key_exp_index, std::move(info), std::move(provider), apostrophe);
1416 std::unique_ptr<PubkeyProvider> InferPubkey(
const CPubKey& pubkey, ParseScriptContext ctx,
const SigningProvider& provider)
1423 if (ctx != ParseScriptContext::TOP && ctx != ParseScriptContext::P2SH && !pubkey.
IsCompressed()) {
1426 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
false);
1429 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
1431 return key_provider;
1434 std::unique_ptr<PubkeyProvider> InferXOnlyPubkey(
const XOnlyPubKey& xkey, ParseScriptContext ctx,
const SigningProvider& provider)
1437 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
true);
1440 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
1442 return key_provider;
1450 using Key = uint32_t;
1456 mutable std::vector<std::unique_ptr<PubkeyProvider>> m_keys;
1458 mutable std::string m_key_parsing_error;
1466 : m_out(
out), m_in(in), m_script_ctx(ctx), m_offset(offset) {}
1468 bool KeyCompare(
const Key& a,
const Key& b)
const {
1469 return *m_keys.at(a) < *m_keys.at(b);
1473 switch (m_script_ctx) {
1480 template<
typename I> std::optional<Key>
FromString(I begin, I end)
const
1483 Key key = m_keys.
size();
1484 auto pk = ParsePubkey(m_offset + key, {&*begin, &*end},
ParseContext(), *m_out, m_key_parsing_error);
1486 m_keys.push_back(std::move(
pk));
1490 std::optional<std::string>
ToString(
const Key& key)
const
1492 return m_keys.at(key)->ToString();
1495 template<
typename I> std::optional<Key> FromPKBytes(I begin, I end)
const
1498 Key key = m_keys.size();
1501 std::copy(begin, end, pubkey.
begin());
1503 m_keys.push_back(std::move(pubkey_provider));
1508 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
1509 m_keys.push_back(std::move(pubkey_provider));
1516 template<
typename I> std::optional<Key> FromPKHBytes(I begin, I end)
const
1518 assert(end - begin == 20);
1521 std::copy(begin, end, hash.
begin());
1525 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
1526 Key key = m_keys.
size();
1527 m_keys.push_back(std::move(pubkey_provider));
1535 return m_script_ctx;
1544 auto expr =
Expr(sp);
1545 if (
Func(
"pk", expr)) {
1546 auto pubkey = ParsePubkey(key_exp_index, expr, ctx,
out,
error);
1552 return std::make_unique<PKDescriptor>(std::move(pubkey), ctx == ParseScriptContext::P2TR);
1554 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) &&
Func(
"pkh", expr)) {
1555 auto pubkey = ParsePubkey(key_exp_index, expr, ctx,
out,
error);
1561 return std::make_unique<PKHDescriptor>(std::move(pubkey));
1562 }
else if (ctx != ParseScriptContext::P2TR &&
Func(
"pkh", expr)) {
1564 error =
"Can only have pkh at top level, in sh(), wsh(), or in tr()";
1567 if (ctx == ParseScriptContext::TOP &&
Func(
"combo", expr)) {
1568 auto pubkey = ParsePubkey(key_exp_index, expr, ctx,
out,
error);
1574 return std::make_unique<ComboDescriptor>(std::move(pubkey));
1575 }
else if (
Func(
"combo", expr)) {
1576 error =
"Can only have combo() at top level";
1579 const bool multi =
Func(
"multi", expr);
1580 const bool sortedmulti = !multi &&
Func(
"sortedmulti", expr);
1581 const bool multi_a = !(multi || sortedmulti) &&
Func(
"multi_a", expr);
1582 const bool sortedmulti_a = !(multi || sortedmulti || multi_a) &&
Func(
"sortedmulti_a", expr);
1583 if (((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && (multi || sortedmulti)) ||
1584 (ctx == ParseScriptContext::P2TR && (multi_a || sortedmulti_a))) {
1585 auto threshold =
Expr(expr);
1587 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1588 if (!
ParseUInt32(std::string(threshold.begin(), threshold.end()), &thres)) {
1589 error =
strprintf(
"Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
1592 size_t script_size = 0;
1593 while (expr.size()) {
1594 if (!
Const(
",", expr)) {
1598 auto arg =
Expr(expr);
1599 auto pk = ParsePubkey(key_exp_index, arg, ctx,
out,
error);
1604 script_size +=
pk->GetSize() + 1;
1605 providers.emplace_back(std::move(
pk));
1614 }
else if (thres < 1) {
1615 error =
strprintf(
"Multisig threshold cannot be %d, must be at least 1", thres);
1617 }
else if (thres > providers.size()) {
1618 error =
strprintf(
"Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
1621 if (ctx == ParseScriptContext::TOP) {
1622 if (providers.size() > 3) {
1623 error =
strprintf(
"Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
1627 if (ctx == ParseScriptContext::P2SH) {
1634 if (multi || sortedmulti) {
1635 return std::make_unique<MultisigDescriptor>(thres, std::move(providers), sortedmulti);
1637 return std::make_unique<MultiADescriptor>(thres, std::move(providers), sortedmulti_a);
1639 }
else if (multi || sortedmulti) {
1640 error =
"Can only have multi/sortedmulti at top level, in sh(), or in wsh()";
1642 }
else if (multi_a || sortedmulti_a) {
1643 error =
"Can only have multi_a/sortedmulti_a inside tr()";
1646 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wpkh", expr)) {
1647 auto pubkey = ParsePubkey(key_exp_index, expr, ParseScriptContext::P2WPKH,
out,
error);
1653 return std::make_unique<WPKHDescriptor>(std::move(pubkey));
1654 }
else if (
Func(
"wpkh", expr)) {
1655 error =
"Can only have wpkh() at top level or inside sh()";
1658 if (ctx == ParseScriptContext::TOP &&
Func(
"sh", expr)) {
1660 if (!desc || expr.size())
return nullptr;
1661 return std::make_unique<SHDescriptor>(std::move(desc));
1662 }
else if (
Func(
"sh", expr)) {
1663 error =
"Can only have sh() at top level";
1666 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wsh", expr)) {
1668 if (!desc || expr.size())
return nullptr;
1669 return std::make_unique<WSHDescriptor>(std::move(desc));
1670 }
else if (
Func(
"wsh", expr)) {
1671 error =
"Can only have wsh() at top level or inside sh()";
1674 if (ctx == ParseScriptContext::TOP &&
Func(
"addr", expr)) {
1677 error =
"Address is not valid";
1680 return std::make_unique<AddressDescriptor>(std::move(dest));
1681 }
else if (
Func(
"addr", expr)) {
1682 error =
"Can only have addr() at top level";
1685 if (ctx == ParseScriptContext::TOP &&
Func(
"tr", expr)) {
1686 auto arg =
Expr(expr);
1687 auto internal_key = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out,
error);
1688 if (!internal_key) {
1693 std::vector<std::unique_ptr<DescriptorImpl>> subscripts;
1694 std::vector<int> depths;
1696 if (!
Const(
",", expr)) {
1703 std::vector<bool> branches;
1708 while (
Const(
"{", expr)) {
1709 branches.push_back(
false);
1716 auto sarg =
Expr(expr);
1717 subscripts.emplace_back(
ParseScript(key_exp_index, sarg, ParseScriptContext::P2TR,
out,
error));
1718 if (!subscripts.back())
return nullptr;
1719 depths.push_back(branches.size());
1721 while (branches.size() && branches.back()) {
1722 if (!
Const(
"}", expr)) {
1726 branches.pop_back();
1729 if (branches.size() && !branches.back()) {
1730 if (!
Const(
",", expr)) {
1734 branches.back() =
true;
1736 }
while (branches.size());
1744 return std::make_unique<TRDescriptor>(std::move(internal_key), std::move(subscripts), std::move(depths));
1745 }
else if (
Func(
"tr", expr)) {
1746 error =
"Can only have tr at top level";
1749 if (ctx == ParseScriptContext::TOP &&
Func(
"rawtr", expr)) {
1750 auto arg =
Expr(expr);
1755 auto output_key = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out,
error);
1756 if (!output_key)
return nullptr;
1758 return std::make_unique<RawTRDescriptor>(std::move(output_key));
1759 }
else if (
Func(
"rawtr", expr)) {
1760 error =
"Can only have rawtr at top level";
1763 if (ctx == ParseScriptContext::TOP &&
Func(
"raw", expr)) {
1764 std::string str(expr.begin(), expr.end());
1766 error =
"Raw script is not hex";
1770 return std::make_unique<RawDescriptor>(
CScript(bytes.begin(), bytes.end()));
1771 }
else if (
Func(
"raw", expr)) {
1772 error =
"Can only have raw() at top level";
1778 KeyParser parser(&
out,
nullptr, script_ctx, key_exp_index);
1781 if (ctx != ParseScriptContext::P2WSH && ctx != ParseScriptContext::P2TR) {
1782 error =
"Miniscript expressions can only be used in wsh or tr.";
1785 if (parser.m_key_parsing_error !=
"") {
1786 error = std::move(parser.m_key_parsing_error);
1789 if (!
node->IsSane() ||
node->IsNotSatisfiable()) {
1791 auto insane_node =
node.get();
1792 if (
const auto sub =
node->FindInsaneSub()) insane_node = sub;
1793 if (
const auto str = insane_node->ToString(parser))
error = *str;
1794 if (!insane_node->IsValid()) {
1795 error +=
" is invalid";
1796 }
else if (!
node->IsSane()) {
1797 error +=
" is not sane";
1798 if (!insane_node->IsNonMalleable()) {
1799 error +=
": malleable witnesses exist";
1800 }
else if (insane_node ==
node.get() && !insane_node->NeedsSignature()) {
1801 error +=
": witnesses without signature exist";
1802 }
else if (!insane_node->CheckTimeLocksMix()) {
1803 error +=
": contains mixes of timelocks expressed in blocks and seconds";
1804 }
else if (!insane_node->CheckDuplicateKey()) {
1805 error +=
": contains duplicate public keys";
1806 }
else if (!insane_node->ValidSatisfactions()) {
1807 error +=
": needs witnesses that may exceed resource limits";
1810 error +=
" is not satisfiable";
1817 key_exp_index += parser.m_keys.size();
1818 return std::make_unique<MiniscriptDescriptor>(std::move(parser.m_keys), std::move(
node));
1821 if (ctx == ParseScriptContext::P2SH) {
1822 error =
"A function is needed within P2SH";
1824 }
else if (ctx == ParseScriptContext::P2WSH) {
1825 error =
"A function is needed within P2WSH";
1828 error =
strprintf(
"'%s' is not a valid descriptor function", std::string(expr.begin(), expr.end()));
1832 std::unique_ptr<DescriptorImpl> InferMultiA(
const CScript& script, ParseScriptContext ctx,
const SigningProvider& provider)
1835 if (!match)
return {};
1836 std::vector<std::unique_ptr<PubkeyProvider>> keys;
1837 keys.reserve(match->second.size());
1838 for (
const auto keyspan : match->second) {
1839 if (keyspan.size() != 32)
return {};
1840 auto key = InferXOnlyPubkey(
XOnlyPubKey{keyspan}, ctx, provider);
1841 if (!key)
return {};
1842 keys.push_back(std::move(key));
1844 return std::make_unique<MultiADescriptor>(match->first, std::move(keys));
1847 std::unique_ptr<DescriptorImpl> InferScript(
const CScript& script, ParseScriptContext ctx,
const SigningProvider& provider)
1849 if (ctx == ParseScriptContext::P2TR && script.
size() == 34 && script[0] == 32 && script[33] ==
OP_CHECKSIG) {
1851 return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx, provider),
true);
1854 if (ctx == ParseScriptContext::P2TR) {
1855 auto ret = InferMultiA(script, ctx, provider);
1859 std::vector<std::vector<unsigned char>> data;
1862 if (txntype ==
TxoutType::PUBKEY && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
1864 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
1865 return std::make_unique<PKDescriptor>(std::move(pubkey_provider));
1868 if (txntype ==
TxoutType::PUBKEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
1872 if (provider.
GetPubKey(keyid, pubkey)) {
1873 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
1874 return std::make_unique<PKHDescriptor>(std::move(pubkey_provider));
1882 if (provider.
GetPubKey(keyid, pubkey)) {
1883 if (
auto pubkey_provider = InferPubkey(pubkey, ParseScriptContext::P2WPKH, provider)) {
1884 return std::make_unique<WPKHDescriptor>(std::move(pubkey_provider));
1888 if (txntype ==
TxoutType::MULTISIG && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
1890 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1891 for (
size_t i = 1; i + 1 < data.size(); ++i) {
1893 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
1894 providers.push_back(std::move(pubkey_provider));
1900 if (ok)
return std::make_unique<MultisigDescriptor>((
int)data[0][0], std::move(providers));
1906 if (provider.
GetCScript(scriptid, subscript)) {
1907 auto sub = InferScript(subscript, ParseScriptContext::P2SH, provider);
1908 if (sub)
return std::make_unique<SHDescriptor>(std::move(sub));
1914 if (provider.
GetCScript(scriptid, subscript)) {
1915 auto sub = InferScript(subscript, ParseScriptContext::P2WSH, provider);
1916 if (sub)
return std::make_unique<WSHDescriptor>(std::move(sub));
1922 std::copy(data[0].begin(), data[0].end(), pubkey.
begin());
1931 std::vector<std::unique_ptr<DescriptorImpl>> subscripts;
1932 std::vector<int> depths;
1933 for (
const auto& [depth, script, leaf_ver] : *tree) {
1934 std::unique_ptr<DescriptorImpl> subdesc;
1936 subdesc = InferScript(
CScript(script.
begin(), script.
end()), ParseScriptContext::P2TR, provider);
1942 subscripts.push_back(std::move(subdesc));
1943 depths.push_back(depth);
1947 auto key = InferXOnlyPubkey(tap.
internal_key, ParseScriptContext::P2TR, provider);
1948 return std::make_unique<TRDescriptor>(std::move(key), std::move(subscripts), std::move(depths));
1954 auto key = InferXOnlyPubkey(pubkey, ParseScriptContext::P2TR, provider);
1956 return std::make_unique<RawTRDescriptor>(std::move(key));
1961 if (ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR) {
1963 KeyParser parser(
nullptr, &provider, script_ctx);
1966 return std::make_unique<MiniscriptDescriptor>(std::move(parser.m_keys), std::move(
node));
1972 if (ctx != ParseScriptContext::TOP)
return nullptr;
1977 return std::make_unique<AddressDescriptor>(std::move(dest));
1981 return std::make_unique<RawDescriptor>(script);
1992 auto check_split =
Split(sp,
'#');
1993 if (check_split.size() > 2) {
1994 error =
"Multiple '#' symbols";
1997 if (check_split.size() == 1 && require_checksum){
1998 error =
"Missing checksum";
2001 if (check_split.size() == 2) {
2002 if (check_split[1].size() != 8) {
2003 error =
strprintf(
"Expected 8 character checksum, not %u characters", check_split[1].size());
2007 auto checksum = DescriptorChecksum(check_split[0]);
2008 if (checksum.empty()) {
2009 error =
"Invalid characters in payload";
2012 if (check_split.size() == 2) {
2013 if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
2014 error =
strprintf(
"Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
2018 if (out_checksum) *out_checksum = std::move(checksum);
2019 sp = check_split[0];
2027 uint32_t key_exp_index = 0;
2029 if (sp.
size() == 0 &&
ret)
return std::unique_ptr<Descriptor>(std::move(
ret));
2044 return InferScript(script, ParseScriptContext::TOP, provider);
2049 std::string desc_str = desc.
ToString(
true);
2063 xpubs[der_index] = xpub;
2083 const auto& der_it = key_exp_it->second.find(der_index);
2084 if (der_it == key_exp_it->second.end())
return false;
2085 xpub = der_it->second;
2103 if (xpub != parent_xpub_pair.second) {
2104 throw std::runtime_error(std::string(__func__) +
": New cached parent xpub does not match already cached parent xpub");
2112 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
2115 if (xpub != derived_xpub_pair.second) {
2116 throw std::runtime_error(std::string(__func__) +
": New cached derived xpub does not match already cached derived xpub");
2120 CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
2121 diff.
CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
2127 if (xpub != lh_xpub_pair.second) {
2128 throw std::runtime_error(std::string(__func__) +
": New cached last hardened xpub does not match already cached last hardened xpub");
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination corresponds to one with an address.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
std::string FormatHDKeypath(const std::vector< uint32_t > &path, bool apostrophe)
#define CHECK_NONFATAL(condition)
Identity function.
An encapsulated private key.
unsigned int size() const
Simple read-only vector-like interface.
bool IsValid() const
Check whether this private key is valid.
bool IsCompressed() const
Check whether the public key corresponding to this private key is (to be) compressed.
CPubKey GetPubKey() const
Compute the public key from a private key.
A reference to a CKey: the Hash160 of its serialized public key.
An encapsulated public key.
bool IsCompressed() const
Check whether this is a compressed public key.
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
bool IsValidNonHybrid() const noexcept
Check if a public key is a syntactically valid compressed or uncompressed key.
A hasher class for SHA-256.
void Finalize(unsigned char hash[OUTPUT_SIZE])
CSHA256 & Write(const unsigned char *data, size_t len)
Serialized script, used inside transaction inputs and outputs.
A reference to a CScript: the Hash160 of its serialization.
Cache for single descriptor's derived extended pubkeys.
bool GetCachedParentExtPubKey(uint32_t key_exp_pos, CExtPubKey &xpub) const
Retrieve a cached parent xpub.
std::unordered_map< uint32_t, ExtPubKeyMap > GetCachedDerivedExtPubKeys() const
Retrieve all cached derived xpubs.
ExtPubKeyMap m_last_hardened_xpubs
Map key expression index -> last hardened xpub.
void CacheDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, const CExtPubKey &xpub)
Cache an xpub derived at an index.
DescriptorCache MergeAndDiff(const DescriptorCache &other)
Combine another DescriptorCache into this one.
ExtPubKeyMap GetCachedParentExtPubKeys() const
Retrieve all cached parent xpubs.
ExtPubKeyMap GetCachedLastHardenedExtPubKeys() const
Retrieve all cached last hardened xpubs.
void CacheParentExtPubKey(uint32_t key_exp_pos, const CExtPubKey &xpub)
Cache a parent xpub.
void CacheLastHardenedExtPubKey(uint32_t key_exp_pos, const CExtPubKey &xpub)
Cache a last hardened xpub.
bool GetCachedDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, CExtPubKey &xpub) const
Retrieve a cached xpub derived at an index.
std::unordered_map< uint32_t, ExtPubKeyMap > m_derived_xpubs
Map key expression index -> map of (key derivation index -> xpub)
bool GetCachedLastHardenedExtPubKey(uint32_t key_exp_pos, CExtPubKey &xpub) const
Retrieve a cached last hardened xpub.
ExtPubKeyMap m_parent_xpubs
Map key expression index -> parent xpub.
An interface to be implemented by keystores that support signing.
virtual bool GetCScript(const CScriptID &scriptid, CScript &script) const
virtual bool GetTaprootSpendData(const XOnlyPubKey &output_key, TaprootSpendData &spenddata) const
virtual bool GetPubKey(const CKeyID &address, CPubKey &pubkey) const
bool GetKeyOriginByXOnly(const XOnlyPubKey &pubkey, KeyOriginInfo &info) const
virtual bool GetKey(const CKeyID &address, CKey &key) const
virtual bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const
A Span is an object that can refer to a contiguous sequence of objects.
constexpr std::size_t size() const noexcept
constexpr C * end() const noexcept
constexpr C * begin() const noexcept
CONSTEXPR_IF_NOT_DEBUG Span< C > first(std::size_t count) const noexcept
Utility class to construct Taproot outputs from internal key and script tree.
WitnessV1Taproot GetOutput()
Compute scriptPubKey (after Finalize()).
bool IsComplete() const
Return whether there were either no leaves, or the leaves form a Huffman tree.
static bool ValidDepths(const std::vector< int > &depths)
Check if a list of depths is legal (will lead to IsComplete()).
TaprootBuilder & Add(int depth, Span< const unsigned char > script, int leaf_version, bool track=true)
Add a new script at a certain depth in the tree.
TaprootBuilder & Finalize(const XOnlyPubKey &internal_key)
Finalize the construction.
const unsigned char * begin() const
static constexpr size_t size()
CPubKey GetEvenCorrespondingCPubKey() const
bool IsFullyValid() const
Determine if this pubkey is fully valid.
constexpr unsigned char * begin()
static const int WITNESS_SCALE_FACTOR
CScript ParseScript(const std::string &s)
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.
uint256 DescriptorID(const Descriptor &desc)
Unique identifier that may not change over time, unless explicitly marked as not backwards compatible...
std::string GetDescriptorChecksum(const std::string &descriptor)
Get the checksum for a descriptor.
std::unique_ptr< Descriptor > Parse(const std::string &descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible.
std::unordered_map< uint32_t, CExtPubKey > ExtPubKeyMap
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
uint160 RIPEMD160(Span< const unsigned char > data)
Compute the 160-bit RIPEMD-160 hash of an array.
static constexpr uint8_t TAPROOT_LEAF_TAPSCRIPT
static constexpr size_t TAPROOT_CONTROL_MAX_NODE_COUNT
std::string EncodeExtKey(const CExtKey &key)
CExtPubKey DecodeExtPubKey(const std::string &str)
CTxDestination DecodeDestination(const std::string &str, std::string &error_msg, std::vector< int > *error_locations)
std::string EncodeSecret(const CKey &key)
std::string EncodeDestination(const CTxDestination &dest)
CKey DecodeSecret(const std::string &str)
std::string EncodeExtPubKey(const CExtPubKey &key)
CExtKey DecodeExtKey(const std::string &str)
bool error(const char *fmt, const Args &... args)
std::shared_ptr< const Node< Key > > NodeRef
constexpr bool IsTapscript(MiniscriptContext ms_ctx)
Whether the context Tapscript, ensuring the only other possibility is P2WSH.
NodeRef< typename Ctx::Key > FromScript(const CScript &script, const Ctx &ctx)
NodeRef< typename Ctx::Key > FromString(const std::string &str, const Ctx &ctx)
Span< const char > Expr(Span< const char > &sp)
Extract the expression that sp begins with.
bool Const(const std::string &str, Span< const char > &sp)
Parse a constant.
bool Func(const std::string &str, Span< const char > &sp)
Parse a function call.
std::vector< T > Split(const Span< const char > &sp, std::string_view separators)
Split a string on any char found in separators, returning a vector.
static OutputType GetOutputType(TxoutType type, bool is_from_p2sh)
static bool IsSegwit(const Descriptor &desc)
Whether the descriptor represents, directly or not, a witness program.
bool operator<(const CNetAddr &a, const CNetAddr &b)
std::optional< OutputType > OutputTypeFromDestination(const CTxDestination &dest)
Get the OutputType for a CTxDestination.
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
std::vector< unsigned char > ToByteVector(const T &in)
static constexpr unsigned int MAX_PUBKEYS_PER_MULTI_A
The limit of keys in OP_CHECKSIGADD-based scripts.
CScript BuildScript(Ts &&... inputs)
Build a script by concatenating other scripts, or any argument accepted by CScript::operator<<.
static const int MAX_PUBKEYS_PER_MULTISIG
constexpr unsigned int GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 byt...
static bool GetPubKey(const SigningProvider &provider, const SignatureData &sigdata, const CKeyID &address, CPubKey &pubkey)
const SigningProvider & DUMMY_SIGNING_PROVIDER
std::optional< std::vector< std::tuple< int, std::vector< unsigned char >, int > > > InferTaprootTree(const TaprootSpendData &spenddata, const XOnlyPubKey &output)
Given a TaprootSpendData and the output key, reconstruct its script tree.
void PolyMod(const std::vector< typename F::Elem > &mod, std::vector< typename F::Elem > &val, const F &field)
Compute the remainder of a polynomial division of val by mod, putting the result in mod.
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char >> &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
std::optional< std::pair< int, std::vector< Span< const unsigned char > > > > MatchMultiA(const CScript &script)
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
std::string ToString(const T &t)
Locale-independent version of std::to_string.
CExtPubKey Neuter() const
bool Derive(CExtKey &out, unsigned int nChild) const
bool Derive(CExtPubKey &out, unsigned int nChild) const
Interface for parsed descriptor objects.
virtual std::optional< int64_t > MaxSatisfactionElems() const =0
Get the maximum size number of stack elements for satisfying this descriptor.
virtual std::optional< OutputType > GetOutputType() const =0
virtual bool ToNormalizedString(const SigningProvider &provider, std::string &out, const DescriptorCache *cache=nullptr) const =0
Convert the descriptor to a normalized string.
virtual std::optional< int64_t > ScriptSize() const =0
Get the size of the scriptPubKey for this descriptor.
virtual std::optional< int64_t > MaxSatisfactionWeight(bool use_max_sig) const =0
Get the maximum size of a satisfaction for this descriptor, in weight units.
virtual std::string ToString(bool compat_format=false) const =0
Convert the descriptor back to a string, undoing parsing.
virtual bool Expand(int pos, const SigningProvider &provider, std::vector< CScript > &output_scripts, FlatSigningProvider &out, DescriptorCache *write_cache=nullptr) const =0
Expand a descriptor at a specified position.
virtual bool IsRange() const =0
Whether the expansion of this descriptor depends on the position.
virtual bool IsSolvable() const =0
Whether this descriptor has all information about signing ignoring lack of private keys.
virtual void ExpandPrivate(int pos, const SigningProvider &provider, FlatSigningProvider &out) const =0
Expand the private key for a descriptor at a specified position, if possible.
virtual bool ToPrivateString(const SigningProvider &provider, std::string &out) const =0
Convert the descriptor to a private string.
virtual bool ExpandFromCache(int pos, const DescriptorCache &read_cache, std::vector< CScript > &output_scripts, FlatSigningProvider &out) const =0
Expand a descriptor at a specified position using cached expansion data.
std::map< CKeyID, CPubKey > pubkeys
unsigned char fingerprint[4]
First 32 bits of the Hash160 of the public key at the root of the path.
std::vector< uint32_t > path
XOnlyPubKey internal_key
The BIP341 internal key.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
bool IsHex(std::string_view str)
bool ParseUInt32(std::string_view str, uint32_t *out)
Convert decimal string to unsigned 32-bit integer with strict parse error feedback.
std::vector< typename std::common_type< Args... >::type > Vector(Args &&... args)
Construct a vector with the specified elements.