93uint64_t
PolyMod(uint64_t c,
int val)
96 c = ((c & 0x7ffffffff) << 5) ^ val;
97 if (c0 & 1) c ^= 0xf5dee51989;
98 if (c0 & 2) c ^= 0xa9fdca3312;
99 if (c0 & 4) c ^= 0x1bab10e32d;
100 if (c0 & 8) c ^= 0x3706b1677a;
101 if (c0 & 16) c ^= 0x644d626ffd;
105std::string DescriptorChecksum(
const std::span<const char>& span)
120 static const std::string INPUT_CHARSET =
121 "0123456789()[],'/*abcdefgh@:$%{}"
122 "IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~"
123 "ijklmnopqrstuvwxyzABCDEFGH`#\"\\ ";
126 static const std::string CHECKSUM_CHARSET =
"qpzry9x8gf2tvdw0s3jn54khce6mua7l";
131 for (
auto ch : span) {
132 auto pos = INPUT_CHARSET.find(ch);
133 if (pos == std::string::npos)
return "";
135 cls = cls * 3 + (pos >> 5);
136 if (++clscount == 3) {
143 if (clscount > 0) c =
PolyMod(c, cls);
144 for (
int j = 0; j < 8; ++j) c =
PolyMod(c, 0);
147 std::string
ret(8,
' ');
148 for (
int j = 0; j < 8; ++j)
ret[j] = CHECKSUM_CHARSET[(c >> (5 * (7 - j))) & 31];
152std::string AddChecksum(
const std::string& str) {
return str +
"#" + DescriptorChecksum(str); }
158typedef std::vector<uint32_t> KeyPath;
166 uint32_t m_expr_index;
169 explicit PubkeyProvider(uint32_t exp_index) : m_expr_index(exp_index) {}
171 virtual ~PubkeyProvider() =
default;
176 bool operator<(PubkeyProvider& other)
const {
179 std::optional<CPubKey> a =
GetPubKey(0, dummy, dummy);
180 std::optional<CPubKey> b = other.GetPubKey(0, dummy, dummy);
193 virtual bool IsRange()
const = 0;
196 virtual size_t GetSize()
const = 0;
198 enum class StringType {
204 virtual std::string
ToString(StringType type=StringType::PUBLIC)
const = 0;
218 virtual std::optional<CPubKey> GetRootPubKey()
const = 0;
220 virtual std::optional<CExtPubKey> GetRootExtPubKey()
const = 0;
223 virtual std::unique_ptr<PubkeyProvider> Clone()
const = 0;
226class OriginPubkeyProvider final :
public PubkeyProvider
229 std::unique_ptr<PubkeyProvider> m_provider;
232 std::string OriginString(StringType type,
bool normalized=
false)
const
235 bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
240 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) {}
243 std::optional<CPubKey> pub = m_provider->GetPubKey(pos, arg,
out, read_cache, write_cache);
244 if (!pub)
return std::nullopt;
245 Assert(
out.pubkeys.contains(pub->GetID()));
246 auto& [pubkey, suborigin] =
out.origins[pub->GetID()];
248 std::copy(std::begin(m_origin.fingerprint), std::end(m_origin.fingerprint), suborigin.fingerprint);
249 suborigin.path.insert(suborigin.path.begin(), m_origin.path.begin(), m_origin.path.end());
252 bool IsRange()
const override {
return m_provider->IsRange(); }
253 size_t GetSize()
const override {
return m_provider->GetSize(); }
254 std::string
ToString(StringType type)
const override {
return "[" + OriginString(type) +
"]" + m_provider->ToString(type); }
258 if (!m_provider->ToPrivateString(arg, sub))
return false;
259 ret =
"[" + OriginString(StringType::PUBLIC) +
"]" + std::move(sub);
265 if (!m_provider->ToNormalizedString(arg, sub, cache))
return false;
271 ret =
"[" + OriginString(StringType::PUBLIC,
true) + std::move(sub);
273 ret =
"[" + OriginString(StringType::PUBLIC,
true) +
"]" + std::move(sub);
279 m_provider->GetPrivKey(pos, arg,
out);
281 std::optional<CPubKey> GetRootPubKey()
const override
283 return m_provider->GetRootPubKey();
285 std::optional<CExtPubKey> GetRootExtPubKey()
const override
287 return m_provider->GetRootExtPubKey();
289 std::unique_ptr<PubkeyProvider> Clone()
const override
291 return std::make_unique<OriginPubkeyProvider>(m_expr_index, m_origin, m_provider->Clone(), m_apostrophe);
296class ConstPubkeyProvider final :
public PubkeyProvider
305 arg.
GetKey(m_pubkey.GetID(), key)))
return std::nullopt;
310 ConstPubkeyProvider(uint32_t exp_index,
const CPubKey& pubkey,
bool xonly) : PubkeyProvider(exp_index), m_pubkey(pubkey), m_xonly(xonly) {}
314 CKeyID keyid = m_pubkey.GetID();
316 out.origins.emplace(keyid, std::make_pair(m_pubkey, info));
317 out.pubkeys.emplace(keyid, m_pubkey);
320 bool IsRange()
const override {
return false; }
321 size_t GetSize()
const override {
return m_pubkey.size(); }
322 std::string
ToString(StringType type)
const override {
return m_xonly ?
HexStr(m_pubkey).substr(2) :
HexStr(m_pubkey); }
325 std::optional<CKey> key = GetPrivKey(arg);
326 if (!key)
return false;
337 std::optional<CKey> key = GetPrivKey(arg);
339 out.keys.emplace(key->GetPubKey().GetID(), *key);
341 std::optional<CPubKey> GetRootPubKey()
const override
345 std::optional<CExtPubKey> GetRootExtPubKey()
const override
349 std::unique_ptr<PubkeyProvider> Clone()
const override
351 return std::make_unique<ConstPubkeyProvider>(m_expr_index, m_pubkey, m_xonly);
355enum class DeriveType {
362class BIP32PubkeyProvider final :
public PubkeyProvider
374 if (!arg.
GetKey(m_root_extkey.pubkey.GetID(), key))
return false;
375 ret.nDepth = m_root_extkey.nDepth;
376 std::copy(m_root_extkey.vchFingerprint, m_root_extkey.vchFingerprint +
sizeof(
ret.vchFingerprint),
ret.vchFingerprint);
377 ret.nChild = m_root_extkey.nChild;
378 ret.chaincode = m_root_extkey.chaincode;
386 if (!GetExtKey(arg, xprv))
return false;
387 for (
auto entry : m_path) {
388 if (!xprv.
Derive(xprv, entry))
return false;
390 last_hardened = xprv;
396 bool IsHardened()
const
398 if (m_derive == DeriveType::HARDENED)
return true;
399 for (
auto entry : m_path) {
400 if (entry >> 31)
return true;
406 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) {}
407 bool IsRange()
const override {
return m_derive != DeriveType::NO; }
408 size_t GetSize()
const override {
return 33; }
412 CKeyID keyid = m_root_extkey.pubkey.GetID();
415 if (m_derive == DeriveType::UNHARDENED) info.
path.push_back((uint32_t)pos);
416 if (m_derive == DeriveType::HARDENED) info.
path.push_back(((uint32_t)pos) | 0x80000000L);
424 if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
425 if (m_derive == DeriveType::HARDENED)
return std::nullopt;
427 if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey))
return std::nullopt;
428 final_extkey = parent_extkey;
429 if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.
Derive(final_extkey, pos);
431 }
else if (IsHardened()) {
434 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return std::nullopt;
435 parent_extkey = xprv.
Neuter();
436 if (m_derive == DeriveType::UNHARDENED) der = xprv.
Derive(xprv, pos);
437 if (m_derive == DeriveType::HARDENED) der = xprv.
Derive(xprv, pos | 0x80000000UL);
438 final_extkey = xprv.
Neuter();
440 last_hardened_extkey = lh_xprv.
Neuter();
443 for (
auto entry : m_path) {
444 if (!parent_extkey.
Derive(parent_extkey, entry))
return std::nullopt;
446 final_extkey = parent_extkey;
447 if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.
Derive(final_extkey, pos);
448 assert(m_derive != DeriveType::HARDENED);
450 if (!der)
return std::nullopt;
457 if (m_derive != DeriveType::HARDENED) {
458 write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
461 write_cache->CacheLastHardenedExtPubKey(m_expr_index, last_hardened_extkey);
463 }
else if (info.
path.size() > 0) {
464 write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey);
468 return final_extkey.
pubkey;
470 std::string
ToString(StringType type,
bool normalized)
const
473 const bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
477 if (m_derive == DeriveType::HARDENED)
ret += use_apostrophe ?
'\'' :
'h';
481 std::string
ToString(StringType type=StringType::PUBLIC)
const override
488 if (!GetExtKey(arg, key))
return false;
492 if (m_derive == DeriveType::HARDENED)
out += m_apostrophe ?
'\'' :
'h';
498 if (m_derive == DeriveType::HARDENED) {
504 int i = (int)m_path.size() - 1;
505 for (; i >= 0; --i) {
506 if (m_path.at(i) >> 31) {
518 for (;
k <= i; ++
k) {
520 origin.
path.push_back(m_path.at(
k));
524 for (;
k < (int)m_path.size(); ++
k) {
525 end_path.push_back(m_path.at(
k));
528 CKeyID id = m_root_extkey.pubkey.GetID();
529 std::copy(
id.begin(),
id.begin() + 4, origin.
fingerprint);
534 if (cache !=
nullptr) {
540 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return false;
550 assert(m_derive == DeriveType::UNHARDENED);
558 if (!GetDerivedExtKey(arg, extkey, dummy))
return;
559 if (m_derive == DeriveType::UNHARDENED && !extkey.
Derive(extkey, pos))
return;
560 if (m_derive == DeriveType::HARDENED && !extkey.
Derive(extkey, pos | 0x80000000UL))
return;
563 std::optional<CPubKey> GetRootPubKey()
const override
567 std::optional<CExtPubKey> GetRootExtPubKey()
const override
569 return m_root_extkey;
571 std::unique_ptr<PubkeyProvider> Clone()
const override
573 return std::make_unique<BIP32PubkeyProvider>(m_expr_index, m_root_extkey, m_path, m_derive, m_apostrophe);
582 const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args;
584 const std::string m_name;
590 const std::vector<std::unique_ptr<DescriptorImpl>> m_subdescriptor_args;
593 virtual std::string ToStringExtra()
const {
return ""; }
605 virtual std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& pubkeys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const = 0;
608 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys,
const std::string&
name) : m_pubkey_args(
std::move(pubkeys)), m_name(
name), m_subdescriptor_args() {}
609 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))) {}
610 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)) {}
612 enum class StringType
623 for (
const auto& arg : m_subdescriptor_args) {
624 if (!arg->IsSolvable())
return false;
632 for (
const auto& pubkey : m_pubkey_args) {
633 if (pubkey->IsRange())
return true;
635 for (
const auto& arg : m_subdescriptor_args) {
636 if (arg->IsRange())
return true;
645 for (
const auto& scriptarg : m_subdescriptor_args) {
646 if (pos++)
ret +=
",";
648 if (!scriptarg->ToStringHelper(arg, tmp, type, cache))
return false;
657 std::string extra = ToStringExtra();
658 size_t pos = extra.size() > 0 ? 1 : 0;
659 std::string
ret = m_name +
"(" + extra;
660 for (
const auto& pubkey : m_pubkey_args) {
661 if (pos++)
ret +=
",";
664 case StringType::NORMALIZED:
665 if (!pubkey->ToNormalizedString(*arg, tmp, cache))
return false;
667 case StringType::PRIVATE:
668 if (!pubkey->ToPrivateString(*arg, tmp))
return false;
670 case StringType::PUBLIC:
671 tmp = pubkey->ToString();
673 case StringType::COMPAT:
674 tmp = pubkey->ToString(PubkeyProvider::StringType::COMPAT);
679 std::string subscript;
680 if (!ToStringSubScriptHelper(arg, subscript, type, cache))
return false;
681 if (pos && subscript.size())
ret +=
',';
682 out = std::move(
ret) + std::move(subscript) +
")";
686 std::string
ToString(
bool compat_format)
const final
689 ToStringHelper(
nullptr,
ret, compat_format ? StringType::COMPAT : StringType::PUBLIC);
690 return AddChecksum(
ret);
695 bool ret = ToStringHelper(&arg,
out, StringType::PRIVATE);
702 bool ret = ToStringHelper(&arg,
out, StringType::NORMALIZED, cache);
711 std::vector<CPubKey> pubkeys;
712 pubkeys.reserve(m_pubkey_args.size());
715 for (
const auto& p : m_pubkey_args) {
716 std::optional<CPubKey> pubkey = p->
GetPubKey(pos, arg, subprovider, read_cache, write_cache);
717 if (!pubkey)
return false;
718 pubkeys.push_back(pubkey.value());
720 std::vector<CScript> subscripts;
721 for (
const auto& subarg : m_subdescriptor_args) {
722 std::vector<CScript> outscripts;
723 if (!subarg->ExpandHelper(pos, arg, read_cache, outscripts, subprovider, write_cache))
return false;
724 assert(outscripts.size() == 1);
725 subscripts.emplace_back(std::move(outscripts[0]));
727 out.Merge(std::move(subprovider));
729 output_scripts = MakeScripts(pubkeys, std::span{subscripts},
out);
735 return ExpandHelper(pos, provider,
nullptr, output_scripts,
out, write_cache);
746 for (
const auto& p : m_pubkey_args) {
747 p->GetPrivKey(pos, provider,
out);
749 for (
const auto& arg : m_subdescriptor_args) {
750 arg->ExpandPrivate(pos, provider,
out);
754 std::optional<OutputType>
GetOutputType()
const override {
return std::nullopt; }
756 std::optional<int64_t>
ScriptSize()
const override {
return {}; }
763 virtual std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const {
return {}; }
770 void GetPubKeys(std::set<CPubKey>& pubkeys, std::set<CExtPubKey>& ext_pubs)
const override
772 for (
const auto& p : m_pubkey_args) {
773 std::optional<CPubKey> pub = p->GetRootPubKey();
774 if (pub) pubkeys.insert(*pub);
775 std::optional<CExtPubKey> ext_pub = p->GetRootExtPubKey();
776 if (ext_pub) ext_pubs.insert(*ext_pub);
778 for (
const auto& arg : m_subdescriptor_args) {
779 arg->GetPubKeys(pubkeys, ext_pubs);
783 virtual std::unique_ptr<DescriptorImpl> Clone()
const = 0;
787class AddressDescriptor final :
public DescriptorImpl
791 std::string ToStringExtra()
const override {
return EncodeDestination(m_destination); }
794 AddressDescriptor(
CTxDestination destination) : DescriptorImpl({},
"addr"), m_destination(std::move(destination)) {}
795 bool IsSolvable() const final {
return false; }
801 bool IsSingleType() const final {
return true; }
802 bool IsSingleKey() const final {
return false; }
803 bool ToPrivateString(
const SigningProvider& arg, std::string&
out)
const final {
return false; }
806 std::unique_ptr<DescriptorImpl> Clone()
const override
808 return std::make_unique<AddressDescriptor>(m_destination);
813class RawDescriptor final :
public DescriptorImpl
817 std::string ToStringExtra()
const override {
return HexStr(m_script); }
818 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript>,
FlatSigningProvider&)
const override {
return Vector(m_script); }
821 bool IsSolvable() const final {
return false; }
829 bool IsSingleType() const final {
return true; }
830 bool IsSingleKey() const final {
return false; }
831 bool ToPrivateString(
const SigningProvider& arg, std::string&
out)
const final {
return false; }
833 std::optional<int64_t> ScriptSize()
const override {
return m_script.size(); }
835 std::unique_ptr<DescriptorImpl> Clone()
const override
837 return std::make_unique<RawDescriptor>(m_script);
842class PKDescriptor final :
public DescriptorImpl
847 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override
857 PKDescriptor(std::unique_ptr<PubkeyProvider> prov,
bool xonly =
false) : DescriptorImpl(
Vector(
std::move(prov)),
"pk"), m_xonly(xonly) {}
858 bool IsSingleType() const final {
return true; }
859 bool IsSingleKey() const final {
return true; }
861 std::optional<int64_t> ScriptSize()
const override {
862 return 1 + (m_xonly ? 32 : m_pubkey_args[0]->GetSize()) + 1;
865 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
866 const auto ecdsa_sig_size = use_max_sig ? 72 : 71;
867 return 1 + (m_xonly ? 65 : ecdsa_sig_size);
870 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
874 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1; }
876 std::unique_ptr<DescriptorImpl> Clone()
const override
878 return std::make_unique<PKDescriptor>(m_pubkey_args.at(0)->Clone(), m_xonly);
883class PKHDescriptor final :
public DescriptorImpl
886 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override
888 CKeyID id = keys[0].GetID();
892 PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"pkh") {}
894 bool IsSingleType() const final {
return true; }
895 bool IsSingleKey() const final {
return true; }
897 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 1 + 20 + 1 + 1; }
899 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
900 const auto sig_size = use_max_sig ? 72 : 71;
901 return 1 +
sig_size + 1 + m_pubkey_args[0]->GetSize();
904 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
908 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
910 std::unique_ptr<DescriptorImpl> Clone()
const override
912 return std::make_unique<PKHDescriptor>(m_pubkey_args.at(0)->Clone());
917class WPKHDescriptor final :
public DescriptorImpl
920 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override
922 CKeyID id = keys[0].GetID();
926 WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"wpkh") {}
928 bool IsSingleType() const final {
return true; }
929 bool IsSingleKey() const final {
return true; }
931 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20; }
933 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
934 const auto sig_size = use_max_sig ? 72 : 71;
938 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
939 return MaxSatSize(use_max_sig);
942 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
944 std::unique_ptr<DescriptorImpl> Clone()
const override
946 return std::make_unique<WPKHDescriptor>(m_pubkey_args.at(0)->Clone());
951class ComboDescriptor final :
public DescriptorImpl
954 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&
out)
const override
956 std::vector<CScript>
ret;
957 CKeyID id = keys[0].GetID();
960 if (keys[0].IsCompressed()) {
963 ret.emplace_back(p2wpkh);
969 ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"combo") {}
970 bool IsSingleType() const final {
return false; }
971 bool IsSingleKey() const final {
return true; }
972 std::unique_ptr<DescriptorImpl> Clone()
const override
974 return std::make_unique<ComboDescriptor>(m_pubkey_args.at(0)->Clone());
979class MultisigDescriptor final :
public DescriptorImpl
981 const int m_threshold;
984 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
985 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override {
987 std::vector<CPubKey> sorted_keys(keys);
988 std::sort(sorted_keys.begin(), sorted_keys.end());
994 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) {}
995 bool IsSingleType() const final {
return true; }
996 bool IsSingleKey() const final {
return false; }
998 std::optional<int64_t> ScriptSize()
const override {
999 const auto n_keys = m_pubkey_args.size();
1000 auto op = [](int64_t acc,
const std::unique_ptr<PubkeyProvider>&
pk) {
return acc + 1 +
pk->GetSize();};
1001 const auto pubkeys_size{std::accumulate(m_pubkey_args.begin(), m_pubkey_args.end(), int64_t{0}, op)};
1005 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1006 const auto sig_size = use_max_sig ? 72 : 71;
1007 return (1 + (1 +
sig_size) * m_threshold);
1010 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1014 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1 + m_threshold; }
1016 std::unique_ptr<DescriptorImpl> Clone()
const override
1018 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1019 providers.reserve(m_pubkey_args.size());
1020 std::transform(m_pubkey_args.begin(), m_pubkey_args.end(), providers.begin(), [](
const std::unique_ptr<PubkeyProvider>& p) { return p->Clone(); });
1021 return std::make_unique<MultisigDescriptor>(m_threshold, std::move(providers), m_sorted);
1026class MultiADescriptor final :
public DescriptorImpl
1028 const int m_threshold;
1029 const bool m_sorted;
1031 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
1032 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override {
1034 std::vector<XOnlyPubKey> xkeys;
1035 xkeys.reserve(keys.size());
1036 for (
const auto& key : keys) xkeys.emplace_back(key);
1037 if (m_sorted) std::sort(xkeys.begin(), xkeys.end());
1039 for (
size_t i = 1; i < keys.size(); ++i) {
1046 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) {}
1047 bool IsSingleType() const final {
return true; }
1048 bool IsSingleKey() const final {
return false; }
1050 std::optional<int64_t> ScriptSize()
const override {
1051 const auto n_keys = m_pubkey_args.size();
1055 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1056 return (1 + 65) * m_threshold + (m_pubkey_args.size() - m_threshold);
1059 std::optional<int64_t> MaxSatisfactionElems()
const override {
return m_pubkey_args.size(); }
1061 std::unique_ptr<DescriptorImpl> Clone()
const override
1063 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1064 providers.reserve(m_pubkey_args.size());
1065 for (
const auto& arg : m_pubkey_args) {
1066 providers.push_back(arg->Clone());
1068 return std::make_unique<MultiADescriptor>(m_threshold, std::move(providers), m_sorted);
1073class SHDescriptor final :
public DescriptorImpl
1076 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1079 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1086 SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"sh") {}
1090 assert(m_subdescriptor_args.size() == 1);
1094 bool IsSingleType() const final {
return true; }
1095 bool IsSingleKey() const final {
return m_subdescriptor_args[0]->IsSingleKey(); }
1097 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20 + 1; }
1099 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1100 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1101 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1105 if (
IsSegwit())
return subscript_weight + *sat_size;
1112 std::optional<int64_t> MaxSatisfactionElems()
const override {
1113 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1117 std::unique_ptr<DescriptorImpl> Clone()
const override
1119 return std::make_unique<SHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1124class WSHDescriptor final :
public DescriptorImpl
1127 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1130 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1134 WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"wsh") {}
1136 bool IsSingleType() const final {
return true; }
1137 bool IsSingleKey() const final {
return m_subdescriptor_args[0]->IsSingleKey(); }
1139 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1141 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1142 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1143 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1150 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1151 return MaxSatSize(use_max_sig);
1154 std::optional<int64_t> MaxSatisfactionElems()
const override {
1155 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1159 std::unique_ptr<DescriptorImpl> Clone()
const override
1161 return std::make_unique<WSHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1166class TRDescriptor final :
public DescriptorImpl
1168 std::vector<int> m_depths;
1170 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1173 assert(m_depths.size() == scripts.size());
1174 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1178 assert(keys.size() == 1);
1180 if (!xpk.IsFullyValid())
return {};
1183 out.tr_trees[output] = builder;
1188 if (m_depths.empty())
return true;
1189 std::vector<bool> path;
1190 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1191 if (pos)
ret +=
',';
1192 while ((
int)path.size() <= m_depths[pos]) {
1193 if (path.size())
ret +=
'{';
1194 path.push_back(
false);
1197 if (!m_subdescriptor_args[pos]->ToStringHelper(arg, tmp, type, cache))
return false;
1199 while (!path.empty() && path.back()) {
1200 if (path.size() > 1)
ret +=
'}';
1203 if (!path.empty()) path.back() =
true;
1208 TRDescriptor(std::unique_ptr<PubkeyProvider> internal_key, std::vector<std::unique_ptr<DescriptorImpl>> descs, std::vector<int> depths) :
1209 DescriptorImpl(
Vector(
std::move(internal_key)),
std::move(descs),
"tr"), m_depths(
std::move(depths))
1211 assert(m_subdescriptor_args.size() == m_depths.size());
1214 bool IsSingleType() const final {
return true; }
1215 bool IsSingleKey() const final {
return false; }
1217 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1219 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1224 std::optional<int64_t> MaxSatisfactionElems()
const override {
1229 std::unique_ptr<DescriptorImpl> Clone()
const override
1231 std::vector<std::unique_ptr<DescriptorImpl>> subdescs;
1232 subdescs.reserve(m_subdescriptor_args.size());
1233 std::transform(m_subdescriptor_args.begin(), m_subdescriptor_args.end(), subdescs.begin(), [](
const std::unique_ptr<DescriptorImpl>& d) { return d->Clone(); });
1234 return std::make_unique<TRDescriptor>(m_pubkey_args.at(0)->Clone(), std::move(subdescs), m_depths);
1248 const std::vector<CPubKey>& m_keys;
1255 uint160 GetHash160(uint32_t key)
const {
1259 return m_keys[key].GetID();
1265 std::vector<unsigned char> ToPKBytes(uint32_t key)
const {
1268 return {m_keys[key].begin(), m_keys[key].end()};
1271 return {xonly_pubkey.
begin(), xonly_pubkey.end()};
1274 std::vector<unsigned char> ToPKHBytes(uint32_t key)
const {
1275 auto id = GetHash160(key);
1276 return {
id.begin(),
id.end()};
1287 const std::vector<std::unique_ptr<PubkeyProvider>>& m_pubkeys;
1293 : m_arg(arg), m_pubkeys(pubkeys), m_private(priv) {}
1295 std::optional<std::string>
ToString(uint32_t key)
const
1299 if (!m_pubkeys[key]->ToPrivateString(*m_arg,
ret))
return {};
1301 ret = m_pubkeys[key]->ToString();
1307class MiniscriptDescriptor final :
public DescriptorImpl
1313 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
1316 const auto script_ctx{
m_node->GetMsCtx()};
1317 for (
const auto& key : keys) {
1321 provider.
pubkeys.emplace(key.GetID(), key);
1324 return Vector(
m_node->ToScript(ScriptMaker(keys, script_ctx)));
1331 bool ToStringHelper(
const SigningProvider* arg, std::string&
out,
const StringType type,
1334 if (
const auto res =
m_node->ToString(StringMaker(arg, m_pubkey_args, type == StringType::PRIVATE))) {
1341 bool IsSolvable()
const override {
return true; }
1342 bool IsSingleType() const final {
return true; }
1343 bool IsSingleKey() const final {
return false; }
1345 std::optional<int64_t> ScriptSize()
const override {
return m_node->ScriptSize(); }
1347 std::optional<int64_t> MaxSatSize(
bool)
const override {
1349 return m_node->GetWitnessSize();
1352 std::optional<int64_t> MaxSatisfactionElems()
const override {
1353 return m_node->GetStackSize();
1356 std::unique_ptr<DescriptorImpl> Clone()
const override
1358 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1359 providers.reserve(m_pubkey_args.size());
1360 for (
const auto& arg : m_pubkey_args) {
1361 providers.push_back(arg->Clone());
1363 return std::make_unique<MiniscriptDescriptor>(std::move(providers),
m_node->Clone());
1368class RawTRDescriptor final :
public DescriptorImpl
1371 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1373 assert(keys.size() == 1);
1375 if (!xpk.IsFullyValid())
return {};
1380 RawTRDescriptor(std::unique_ptr<PubkeyProvider> output_key) : DescriptorImpl(
Vector(
std::move(output_key)),
"rawtr") {}
1382 bool IsSingleType() const final {
return true; }
1383 bool IsSingleKey() const final {
return false; }
1385 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1387 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1392 std::optional<int64_t> MaxSatisfactionElems()
const override {
1397 std::unique_ptr<DescriptorImpl> Clone()
const override
1399 return std::make_unique<RawTRDescriptor>(m_pubkey_args.at(0)->Clone());
1407enum class ParseScriptContext {
1415std::optional<uint32_t> ParseKeyPathNum(std::span<const char> elem,
bool& apostrophe, std::string& error)
1417 bool hardened =
false;
1418 if (elem.size() > 0) {
1419 const char last = elem[elem.size() - 1];
1420 if (last ==
'\'' || last ==
'h') {
1421 elem = elem.first(elem.size() - 1);
1423 apostrophe = last ==
'\'';
1426 const auto p{ToIntegral<uint32_t>(std::string_view{elem.begin(), elem.end()})};
1428 error =
strprintf(
"Key path value '%s' is not a valid uint32", std::string_view{elem.begin(), elem.end()});
1429 return std::nullopt;
1430 }
else if (*p > 0x7FFFFFFFUL) {
1431 error =
strprintf(
"Key path value %u is out of range", *p);
1432 return std::nullopt;
1435 return std::make_optional<uint32_t>(*p | (((uint32_t)hardened) << 31));
1448[[nodiscard]]
bool ParseKeyPath(
const std::vector<std::span<const char>>&
split, std::vector<KeyPath>&
out,
bool& apostrophe, std::string& error,
bool allow_multipath)
1451 struct MultipathSubstitutes {
1452 size_t placeholder_index;
1453 std::vector<uint32_t>
values;
1455 std::optional<MultipathSubstitutes> substitutes;
1457 for (
size_t i = 1; i <
split.size(); ++i) {
1458 const std::span<const char>& elem =
split[i];
1461 if (!elem.empty() && elem.front() ==
'<' && elem.back() ==
'>') {
1462 if (!allow_multipath) {
1463 error =
strprintf(
"Key path value '%s' specifies multipath in a section where multipath is not allowed", std::string(elem.begin(), elem.end()));
1467 error =
"Multiple multipath key path specifiers found";
1472 std::vector<std::span<const char>> nums =
Split(std::span(elem.begin()+1, elem.end()-1),
";");
1473 if (nums.size() < 2) {
1474 error =
"Multipath key path specifiers must have at least two items";
1478 substitutes.emplace();
1479 std::unordered_set<uint32_t> seen_substitutes;
1480 for (
const auto& num : nums) {
1481 const auto& op_num = ParseKeyPathNum(num, apostrophe, error);
1482 if (!op_num)
return false;
1483 auto [
_, inserted] = seen_substitutes.insert(*op_num);
1485 error =
strprintf(
"Duplicated key path value %u in multipath specifier", *op_num);
1488 substitutes->values.emplace_back(*op_num);
1491 path.emplace_back();
1492 substitutes->placeholder_index = path.size() - 1;
1494 const auto& op_num = ParseKeyPathNum(elem, apostrophe, error);
1495 if (!op_num)
return false;
1496 path.emplace_back(*op_num);
1501 out.emplace_back(std::move(path));
1504 for (uint32_t substitute : substitutes->values) {
1505 KeyPath branch_path = path;
1506 branch_path[substitutes->placeholder_index] = substitute;
1507 out.emplace_back(std::move(branch_path));
1514std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkeyInner(uint32_t key_exp_index,
const std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out,
bool& apostrophe, std::string& error)
1516 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
1517 bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
1519 std::string str(
split[0].begin(),
split[0].end());
1520 if (str.size() == 0) {
1521 error =
"No key provided";
1525 error =
strprintf(
"Key '%s' is invalid due to whitespace", str);
1528 if (
split.size() == 1) {
1532 if (pubkey.IsValid() && !pubkey.IsValidNonHybrid()) {
1533 error =
"Hybrid public keys are not allowed";
1536 if (pubkey.IsFullyValid()) {
1537 if (permit_uncompressed || pubkey.IsCompressed()) {
1538 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
false));
1541 error =
"Uncompressed keys are not allowed";
1544 }
else if (
data.size() == 32 && ctx == ParseScriptContext::P2TR) {
1545 unsigned char fullkey[33] = {0x02};
1546 std::copy(
data.begin(),
data.end(), fullkey + 1);
1547 pubkey.Set(std::begin(fullkey), std::end(fullkey));
1548 if (pubkey.IsFullyValid()) {
1549 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
true));
1553 error =
strprintf(
"Pubkey '%s' is invalid", str);
1560 out.keys.emplace(pubkey.
GetID(), key);
1561 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, ctx == ParseScriptContext::P2TR));
1564 error =
"Uncompressed keys are not allowed";
1572 error =
strprintf(
"key '%s' is not valid", str);
1575 std::vector<KeyPath> paths;
1576 DeriveType type = DeriveType::NO;
1577 if (std::ranges::equal(
split.back(), std::span{
"*"}.first(1))) {
1579 type = DeriveType::UNHARDENED;
1580 }
else if (std::ranges::equal(
split.back(), std::span{
"*'"}.first(2)) || std::ranges::equal(
split.back(), std::span{
"*h"}.first(2))) {
1581 apostrophe = std::ranges::equal(
split.back(), std::span{
"*'"}.first(2));
1583 type = DeriveType::HARDENED;
1585 if (!ParseKeyPath(
split, paths, apostrophe, error,
true))
return {};
1587 extpubkey = extkey.
Neuter();
1590 for (
auto& path : paths) {
1591 ret.emplace_back(std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type, apostrophe));
1597std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkey(uint32_t key_exp_index,
const std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out, std::string& error)
1599 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
1600 auto origin_split =
Split(sp,
']');
1601 if (origin_split.size() > 2) {
1602 error =
"Multiple ']' characters found for a single pubkey";
1606 bool apostrophe =
false;
1607 if (origin_split.size() == 1) {
1608 return ParsePubkeyInner(key_exp_index, origin_split[0], ctx,
out, apostrophe, error);
1610 if (origin_split[0].empty() || origin_split[0][0] !=
'[') {
1611 error =
strprintf(
"Key origin start '[ character expected but not found, got '%c' instead",
1612 origin_split[0].empty() ?
']' : origin_split[0][0]);
1615 auto slash_split =
Split(origin_split[0].subspan(1),
'/');
1616 if (slash_split[0].size() != 8) {
1617 error =
strprintf(
"Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
1620 std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
1621 if (!
IsHex(fpr_hex)) {
1622 error =
strprintf(
"Fingerprint '%s' is not hex", fpr_hex);
1625 auto fpr_bytes =
ParseHex(fpr_hex);
1627 static_assert(
sizeof(info.
fingerprint) == 4,
"Fingerprint must be 4 bytes");
1628 assert(fpr_bytes.size() == 4);
1629 std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.
fingerprint);
1630 std::vector<KeyPath> path;
1631 if (!ParseKeyPath(slash_split, path, apostrophe, error,
false))
return {};
1632 info.
path = path.at(0);
1633 auto providers = ParsePubkeyInner(key_exp_index, origin_split[1], ctx,
out, apostrophe, error);
1634 if (providers.empty())
return {};
1635 ret.reserve(providers.size());
1636 for (
auto& prov : providers) {
1637 ret.emplace_back(std::make_unique<OriginPubkeyProvider>(key_exp_index, info, std::move(prov), apostrophe));
1642std::unique_ptr<PubkeyProvider> InferPubkey(
const CPubKey& pubkey, ParseScriptContext ctx,
const SigningProvider& provider)
1649 if (ctx != ParseScriptContext::TOP && ctx != ParseScriptContext::P2SH && !pubkey.
IsCompressed()) {
1652 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
false);
1655 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
1657 return key_provider;
1660std::unique_ptr<PubkeyProvider> InferXOnlyPubkey(
const XOnlyPubKey& xkey, ParseScriptContext ctx,
const SigningProvider& provider)
1663 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
true);
1666 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
1668 return key_provider;
1676 using Key = uint32_t;
1682 mutable std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> m_keys;
1684 mutable std::string m_key_parsing_error;
1692 : m_out(
out), m_in(in), m_script_ctx(ctx), m_offset(offset) {}
1694 bool KeyCompare(
const Key& a,
const Key& b)
const {
1695 return *m_keys.at(a).at(0) < *m_keys.at(b).at(0);
1699 switch (m_script_ctx) {
1706 template<
typename I> std::optional<Key>
FromString(I begin, I end)
const
1709 Key key = m_keys.
size();
1710 auto pk = ParsePubkey(m_offset + key, {&*begin, &*end},
ParseContext(), *m_out, m_key_parsing_error);
1711 if (
pk.empty())
return {};
1712 m_keys.emplace_back(std::move(
pk));
1716 std::optional<std::string>
ToString(
const Key& key)
const
1718 return m_keys.at(key).at(0)->ToString();
1721 template<
typename I> std::optional<Key> FromPKBytes(I begin, I end)
const
1724 Key key = m_keys.size();
1727 std::copy(begin, end, pubkey.
begin());
1728 if (
auto pubkey_provider = InferXOnlyPubkey(pubkey,
ParseContext(), *m_in)) {
1729 m_keys.emplace_back();
1730 m_keys.back().push_back(std::move(pubkey_provider));
1735 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
1736 m_keys.emplace_back();
1737 m_keys.back().push_back(std::move(pubkey_provider));
1744 template<
typename I> std::optional<Key> FromPKHBytes(I begin, I end)
const
1746 assert(end - begin == 20);
1749 std::copy(begin, end, hash.
begin());
1753 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
1754 Key key = m_keys.
size();
1755 m_keys.emplace_back();
1756 m_keys.back().push_back(std::move(pubkey_provider));
1764 return m_script_ctx;
1770std::vector<std::unique_ptr<DescriptorImpl>>
ParseScript(uint32_t& key_exp_index, std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out, std::string& error)
1773 Assume(ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR);
1774 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
1775 auto expr =
Expr(sp);
1776 if (
Func(
"pk", expr)) {
1777 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
1778 if (pubkeys.empty()) {
1783 for (
auto& pubkey : pubkeys) {
1784 ret.emplace_back(std::make_unique<PKDescriptor>(std::move(pubkey), ctx == ParseScriptContext::P2TR));
1788 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) &&
Func(
"pkh", expr)) {
1789 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
1790 if (pubkeys.empty()) {
1795 for (
auto& pubkey : pubkeys) {
1796 ret.emplace_back(std::make_unique<PKHDescriptor>(std::move(pubkey)));
1800 if (ctx == ParseScriptContext::TOP &&
Func(
"combo", expr)) {
1801 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
1802 if (pubkeys.empty()) {
1803 error =
strprintf(
"combo(): %s", error);
1807 for (
auto& pubkey : pubkeys) {
1808 ret.emplace_back(std::make_unique<ComboDescriptor>(std::move(pubkey)));
1811 }
else if (
Func(
"combo", expr)) {
1812 error =
"Can only have combo() at top level";
1815 const bool multi =
Func(
"multi", expr);
1816 const bool sortedmulti = !multi &&
Func(
"sortedmulti", expr);
1817 const bool multi_a = !(multi || sortedmulti) &&
Func(
"multi_a", expr);
1818 const bool sortedmulti_a = !(multi || sortedmulti || multi_a) &&
Func(
"sortedmulti_a", expr);
1819 if (((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && (multi || sortedmulti)) ||
1820 (ctx == ParseScriptContext::P2TR && (multi_a || sortedmulti_a))) {
1821 auto threshold =
Expr(expr);
1823 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
1824 if (
const auto maybe_thres{ToIntegral<uint32_t>(std::string_view{threshold.begin(), threshold.end()})}) {
1825 thres = *maybe_thres;
1827 error =
strprintf(
"Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
1830 size_t script_size = 0;
1831 size_t max_providers_len = 0;
1832 while (expr.size()) {
1833 if (!
Const(
",", expr)) {
1834 error =
strprintf(
"Multi: expected ',', got '%c'", expr[0]);
1837 auto arg =
Expr(expr);
1838 auto pks = ParsePubkey(key_exp_index, arg, ctx,
out, error);
1843 script_size += pks.at(0)->GetSize() + 1;
1844 max_providers_len = std::max(max_providers_len, pks.size());
1845 providers.emplace_back(std::move(pks));
1854 }
else if (thres < 1) {
1855 error =
strprintf(
"Multisig threshold cannot be %d, must be at least 1", thres);
1857 }
else if (thres > providers.size()) {
1858 error =
strprintf(
"Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
1861 if (ctx == ParseScriptContext::TOP) {
1862 if (providers.size() > 3) {
1863 error =
strprintf(
"Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
1867 if (ctx == ParseScriptContext::P2SH) {
1877 for (
auto& vec : providers) {
1878 if (vec.size() == 1) {
1879 for (
size_t i = 1; i < max_providers_len; ++i) {
1880 vec.emplace_back(vec.at(0)->Clone());
1882 }
else if (vec.size() != max_providers_len) {
1883 error =
strprintf(
"multi(): Multipath derivation paths have mismatched lengths");
1889 for (
size_t i = 0; i < max_providers_len; ++i) {
1891 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
1892 pubs.reserve(providers.size());
1893 for (
auto& pub : providers) {
1894 pubs.emplace_back(std::move(pub.at(i)));
1896 if (multi || sortedmulti) {
1897 ret.emplace_back(std::make_unique<MultisigDescriptor>(thres, std::move(pubs), sortedmulti));
1899 ret.emplace_back(std::make_unique<MultiADescriptor>(thres, std::move(pubs), sortedmulti_a));
1903 }
else if (multi || sortedmulti) {
1904 error =
"Can only have multi/sortedmulti at top level, in sh(), or in wsh()";
1906 }
else if (multi_a || sortedmulti_a) {
1907 error =
"Can only have multi_a/sortedmulti_a inside tr()";
1910 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wpkh", expr)) {
1911 auto pubkeys = ParsePubkey(key_exp_index, expr, ParseScriptContext::P2WPKH,
out, error);
1912 if (pubkeys.empty()) {
1917 for (
auto& pubkey : pubkeys) {
1918 ret.emplace_back(std::make_unique<WPKHDescriptor>(std::move(pubkey)));
1921 }
else if (
Func(
"wpkh", expr)) {
1922 error =
"Can only have wpkh() at top level or inside sh()";
1925 if (ctx == ParseScriptContext::TOP &&
Func(
"sh", expr)) {
1926 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2SH,
out, error);
1927 if (descs.empty() || expr.size())
return {};
1928 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
1929 ret.reserve(descs.size());
1930 for (
auto& desc : descs) {
1931 ret.push_back(std::make_unique<SHDescriptor>(std::move(desc)));
1934 }
else if (
Func(
"sh", expr)) {
1935 error =
"Can only have sh() at top level";
1938 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wsh", expr)) {
1939 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH,
out, error);
1940 if (descs.empty() || expr.size())
return {};
1941 for (
auto& desc : descs) {
1942 ret.emplace_back(std::make_unique<WSHDescriptor>(std::move(desc)));
1945 }
else if (
Func(
"wsh", expr)) {
1946 error =
"Can only have wsh() at top level or inside sh()";
1949 if (ctx == ParseScriptContext::TOP &&
Func(
"addr", expr)) {
1952 error =
"Address is not valid";
1955 ret.emplace_back(std::make_unique<AddressDescriptor>(std::move(dest)));
1957 }
else if (
Func(
"addr", expr)) {
1958 error =
"Can only have addr() at top level";
1961 if (ctx == ParseScriptContext::TOP &&
Func(
"tr", expr)) {
1962 auto arg =
Expr(expr);
1963 auto internal_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
1964 if (internal_keys.empty()) {
1968 size_t max_providers_len = internal_keys.size();
1970 std::vector<std::vector<std::unique_ptr<DescriptorImpl>>> subscripts;
1971 std::vector<int> depths;
1973 if (!
Const(
",", expr)) {
1974 error =
strprintf(
"tr: expected ',', got '%c'", expr[0]);
1980 std::vector<bool> branches;
1985 while (
Const(
"{", expr)) {
1986 branches.push_back(
false);
1993 auto sarg =
Expr(expr);
1994 subscripts.emplace_back(
ParseScript(key_exp_index, sarg, ParseScriptContext::P2TR,
out, error));
1995 if (subscripts.back().empty())
return {};
1996 max_providers_len = std::max(max_providers_len, subscripts.back().size());
1997 depths.push_back(branches.size());
1999 while (branches.size() && branches.back()) {
2000 if (!
Const(
"}", expr)) {
2001 error =
strprintf(
"tr(): expected '}' after script expression");
2004 branches.pop_back();
2007 if (branches.size() && !branches.back()) {
2008 if (!
Const(
",", expr)) {
2009 error =
strprintf(
"tr(): expected ',' after script expression");
2012 branches.back() =
true;
2014 }
while (branches.size());
2017 error =
strprintf(
"tr(): expected ')' after script expression");
2025 for (
auto& vec : subscripts) {
2026 if (vec.size() == 1) {
2027 for (
size_t i = 1; i < max_providers_len; ++i) {
2028 vec.emplace_back(vec.at(0)->Clone());
2030 }
else if (vec.size() != max_providers_len) {
2031 error =
strprintf(
"tr(): Multipath subscripts have mismatched lengths");
2036 if (internal_keys.size() > 1 && internal_keys.size() != max_providers_len) {
2037 error =
strprintf(
"tr(): Multipath internal key mismatches multipath subscripts lengths");
2041 while (internal_keys.size() < max_providers_len) {
2042 internal_keys.emplace_back(internal_keys.at(0)->Clone());
2046 for (
size_t i = 0; i < max_providers_len; ++i) {
2048 std::vector<std::unique_ptr<DescriptorImpl>> this_subs;
2049 this_subs.reserve(subscripts.size());
2050 for (
auto& subs : subscripts) {
2051 this_subs.emplace_back(std::move(subs.at(i)));
2053 ret.emplace_back(std::make_unique<TRDescriptor>(std::move(internal_keys.at(i)), std::move(this_subs), depths));
2058 }
else if (
Func(
"tr", expr)) {
2059 error =
"Can only have tr at top level";
2062 if (ctx == ParseScriptContext::TOP &&
Func(
"rawtr", expr)) {
2063 auto arg =
Expr(expr);
2065 error =
strprintf(
"rawtr(): only one key expected.");
2068 auto output_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
2069 if (output_keys.empty()) {
2070 error =
strprintf(
"rawtr(): %s", error);
2074 for (
auto& pubkey : output_keys) {
2075 ret.emplace_back(std::make_unique<RawTRDescriptor>(std::move(pubkey)));
2078 }
else if (
Func(
"rawtr", expr)) {
2079 error =
"Can only have rawtr at top level";
2082 if (ctx == ParseScriptContext::TOP &&
Func(
"raw", expr)) {
2083 std::string str(expr.begin(), expr.end());
2085 error =
"Raw script is not hex";
2089 ret.emplace_back(std::make_unique<RawDescriptor>(
CScript(bytes.begin(), bytes.end())));
2091 }
else if (
Func(
"raw", expr)) {
2092 error =
"Can only have raw() at top level";
2098 KeyParser parser(&
out,
nullptr, script_ctx, key_exp_index);
2100 if (parser.m_key_parsing_error !=
"") {
2101 error = std::move(parser.m_key_parsing_error);
2105 if (ctx != ParseScriptContext::P2WSH && ctx != ParseScriptContext::P2TR) {
2106 error =
"Miniscript expressions can only be used in wsh or tr.";
2109 if (!
node->IsSane() ||
node->IsNotSatisfiable()) {
2111 auto insane_node =
node.get();
2112 if (
const auto sub =
node->FindInsaneSub()) insane_node = sub;
2113 if (
const auto str = insane_node->ToString(parser)) error = *str;
2114 if (!insane_node->IsValid()) {
2115 error +=
" is invalid";
2116 }
else if (!
node->IsSane()) {
2117 error +=
" is not sane";
2118 if (!insane_node->IsNonMalleable()) {
2119 error +=
": malleable witnesses exist";
2120 }
else if (insane_node ==
node.get() && !insane_node->NeedsSignature()) {
2121 error +=
": witnesses without signature exist";
2122 }
else if (!insane_node->CheckTimeLocksMix()) {
2123 error +=
": contains mixes of timelocks expressed in blocks and seconds";
2124 }
else if (!insane_node->CheckDuplicateKey()) {
2125 error +=
": contains duplicate public keys";
2126 }
else if (!insane_node->ValidSatisfactions()) {
2127 error +=
": needs witnesses that may exceed resource limits";
2130 error +=
" is not satisfiable";
2137 key_exp_index += parser.m_keys.size();
2140 size_t num_multipath = std::max_element(parser.m_keys.begin(), parser.m_keys.end(),
2141 [](
const std::vector<std::unique_ptr<PubkeyProvider>>& a,
const std::vector<std::unique_ptr<PubkeyProvider>>& b) {
2142 return a.size() < b.size();
2145 for (
auto& vec : parser.m_keys) {
2146 if (vec.size() == 1) {
2147 for (
size_t i = 1; i < num_multipath; ++i) {
2148 vec.emplace_back(vec.at(0)->Clone());
2150 }
else if (vec.size() != num_multipath) {
2151 error =
strprintf(
"Miniscript: Multipath derivation paths have mismatched lengths");
2157 for (
size_t i = 0; i < num_multipath; ++i) {
2159 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2160 pubs.reserve(parser.m_keys.size());
2161 for (
auto& pub : parser.m_keys) {
2162 pubs.emplace_back(std::move(pub.at(i)));
2164 ret.emplace_back(std::make_unique<MiniscriptDescriptor>(std::move(pubs),
node->Clone()));
2169 if (ctx == ParseScriptContext::P2SH) {
2170 error =
"A function is needed within P2SH";
2172 }
else if (ctx == ParseScriptContext::P2WSH) {
2173 error =
"A function is needed within P2WSH";
2176 error =
strprintf(
"'%s' is not a valid descriptor function", std::string(expr.begin(), expr.end()));
2183 if (!match)
return {};
2184 std::vector<std::unique_ptr<PubkeyProvider>> keys;
2185 keys.reserve(match->second.size());
2186 for (
const auto keyspan : match->second) {
2187 if (keyspan.size() != 32)
return {};
2188 auto key = InferXOnlyPubkey(
XOnlyPubKey{keyspan}, ctx, provider);
2189 if (!key)
return {};
2190 keys.push_back(std::move(key));
2192 return std::make_unique<MultiADescriptor>(match->first, std::move(keys));
2200 return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx, provider),
true);
2203 if (ctx == ParseScriptContext::P2TR) {
2204 auto ret = InferMultiA(
script, ctx, provider);
2208 std::vector<std::vector<unsigned char>>
data;
2211 if (txntype ==
TxoutType::PUBKEY && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2213 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2214 return std::make_unique<PKDescriptor>(std::move(pubkey_provider));
2217 if (txntype ==
TxoutType::PUBKEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2221 if (provider.
GetPubKey(keyid, pubkey)) {
2222 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2223 return std::make_unique<PKHDescriptor>(std::move(pubkey_provider));
2231 if (provider.
GetPubKey(keyid, pubkey)) {
2232 if (
auto pubkey_provider = InferPubkey(pubkey, ParseScriptContext::P2WPKH, provider)) {
2233 return std::make_unique<WPKHDescriptor>(std::move(pubkey_provider));
2237 if (txntype ==
TxoutType::MULTISIG && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2239 std::vector<std::unique_ptr<PubkeyProvider>> providers;
2240 for (
size_t i = 1; i + 1 <
data.size(); ++i) {
2242 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2243 providers.push_back(std::move(pubkey_provider));
2249 if (ok)
return std::make_unique<MultisigDescriptor>((
int)
data[0][0], std::move(providers));
2255 if (provider.
GetCScript(scriptid, subscript)) {
2256 auto sub = InferScript(subscript, ParseScriptContext::P2SH, provider);
2257 if (sub)
return std::make_unique<SHDescriptor>(std::move(sub));
2263 if (provider.
GetCScript(scriptid, subscript)) {
2264 auto sub = InferScript(subscript, ParseScriptContext::P2WSH, provider);
2265 if (sub)
return std::make_unique<WSHDescriptor>(std::move(sub));
2280 std::vector<std::unique_ptr<DescriptorImpl>> subscripts;
2281 std::vector<int> depths;
2282 for (
const auto& [depth,
script, leaf_ver] : *tree) {
2283 std::unique_ptr<DescriptorImpl> subdesc;
2285 subdesc = InferScript(
CScript(
script.begin(),
script.end()), ParseScriptContext::P2TR, provider);
2291 subscripts.push_back(std::move(subdesc));
2292 depths.push_back(depth);
2296 auto key = InferXOnlyPubkey(tap.
internal_key, ParseScriptContext::P2TR, provider);
2297 return std::make_unique<TRDescriptor>(std::move(key), std::move(subscripts), std::move(depths));
2303 auto key = InferXOnlyPubkey(pubkey, ParseScriptContext::P2TR, provider);
2305 return std::make_unique<RawTRDescriptor>(std::move(key));
2310 if (ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR) {
2312 KeyParser parser(
nullptr, &provider, script_ctx);
2315 std::vector<std::unique_ptr<PubkeyProvider>> keys;
2316 keys.reserve(parser.m_keys.size());
2317 for (
auto& key : parser.m_keys) {
2318 keys.emplace_back(std::move(key.at(0)));
2320 return std::make_unique<MiniscriptDescriptor>(std::move(keys), std::move(
node));
2326 if (ctx != ParseScriptContext::TOP)
return nullptr;
2331 return std::make_unique<AddressDescriptor>(std::move(dest));
2335 return std::make_unique<RawDescriptor>(
script);
2342bool CheckChecksum(std::span<const char>& sp,
bool require_checksum, std::string& error, std::string* out_checksum =
nullptr)
2344 auto check_split =
Split(sp,
'#');
2345 if (check_split.size() > 2) {
2346 error =
"Multiple '#' symbols";
2349 if (check_split.size() == 1 && require_checksum){
2350 error =
"Missing checksum";
2353 if (check_split.size() == 2) {
2354 if (check_split[1].size() != 8) {
2355 error =
strprintf(
"Expected 8 character checksum, not %u characters", check_split[1].size());
2359 auto checksum = DescriptorChecksum(check_split[0]);
2360 if (checksum.empty()) {
2361 error =
"Invalid characters in payload";
2364 if (check_split.size() == 2) {
2365 if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
2366 error =
strprintf(
"Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
2370 if (out_checksum) *out_checksum = std::move(checksum);
2371 sp = check_split[0];
2377 std::span<const char> sp{descriptor};
2379 uint32_t key_exp_index = 0;
2381 if (sp.size() == 0 && !
ret.empty()) {
2382 std::vector<std::unique_ptr<Descriptor>> descs;
2383 descs.reserve(
ret.size());
2384 for (
auto& r :
ret) {
2385 descs.emplace_back(std::unique_ptr<Descriptor>(std::move(r)));
2396 std::span<const char> sp{descriptor};
2403 return InferScript(
script, ParseScriptContext::TOP, provider);
2408 std::string desc_str = desc.
ToString(
true);
2422 xpubs[der_index] = xpub;
2442 const auto& der_it = key_exp_it->second.find(der_index);
2443 if (der_it == key_exp_it->second.end())
return false;
2444 xpub = der_it->second;
2462 if (xpub != parent_xpub_pair.second) {
2463 throw std::runtime_error(std::string(__func__) +
": New cached parent xpub does not match already cached parent xpub");
2471 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
2474 if (xpub != derived_xpub_pair.second) {
2475 throw std::runtime_error(std::string(__func__) +
": New cached derived xpub does not match already cached derived xpub");
2479 CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
2480 diff.
CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
2486 if (xpub != lh_xpub_pair.second) {
2487 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, PayToAnchor, 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.
#define Assert(val)
Identity function.
#define Assume(val)
Assume is the 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
bool GetKeyByXOnly(const XOnlyPubKey &pubkey, CKey &key) 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
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.
TaprootBuilder & Add(int depth, std::span< const unsigned char > script, int leaf_version, bool track=true)
Add a new script at a certain depth in the tree.
static bool ValidDepths(const std::vector< int > &depths)
Check if a list of depths is legal (will lead to IsComplete()).
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)
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
uint160 RIPEMD160(std::span< const unsigned char > data)
Compute the 160-bit RIPEMD-160 hash of an array.
std::string HexStr(const std::span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
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)
NodeRef< typename Ctx::Key > FromString(const std::string &str, const Ctx &ctx)
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)
std::unique_ptr< const Node< Key > > NodeRef
std::span< const char > Expr(std::span< const char > &sp)
Extract the expression that sp begins with.
bool Const(const std::string &str, std::span< const char > &sp)
Parse a constant.
bool Func(const std::string &str, std::span< const char > &sp)
Parse a function call.
static std::vector< std::string > split(const std::string &str, const std::string &delims=" \t")
std::vector< T > Split(const std::span< const char > &sp, std::string_view separators)
Split a string on any char found in separators, returning a vector.
std::string ToString(const T &t)
Locale-independent version of std::to_string.
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.
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible.
uint256 DescriptorID(const Descriptor &desc)
Unique identifier that may not change over time, unless explicitly marked as not backwards compatible...
bool CheckChecksum(std::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.
std::vector< std::unique_ptr< Descriptor > > Parse(const std::string &descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
std::string GetDescriptorChecksum(const std::string &descriptor)
Get the checksum for a descriptor.
std::unordered_map< uint32_t, CExtPubKey > ExtPubKeyMap
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
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
std::vector< unsigned char > ToByteVector(const T &in)
static const int64_t values[]
A selection of numbers that do not trigger int64_t overflow when added/subtracted.
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)
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.
const SigningProvider & DUMMY_SIGNING_PROVIDER
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.
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
std::optional< std::pair< int, std::vector< std::span< const unsigned char > > > > MatchMultiA(const CScript &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.
constexpr bool IsSpace(char c) noexcept
Tests if the given character is a whitespace character.
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 void GetPubKeys(std::set< CPubKey > &pubkeys, std::set< CExtPubKey > &ext_pubs) const =0
Return all (extended) public keys for this descriptor, including any from subdescriptors.
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 > 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 std::optional< OutputType > GetOutputType() const =0
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 std::optional< int64_t > ScriptSize() const =0
Get the size of the scriptPubKey for this descriptor.
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.
bool GetPubKey(const CKeyID &keyid, CPubKey &pubkey) const override
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.
consteval auto _(util::TranslatedLiteral str)
bool IsHex(std::string_view str)
std::vector< std::common_type_t< Args... > > Vector(Args &&... args)
Construct a vector with the specified elements.