84 uint64_t
PolyMod(uint64_t c,
int val)
87 c = ((c & 0x7ffffffff) << 5) ^ val;
88 if (c0 & 1) c ^= 0xf5dee51989;
89 if (c0 & 2) c ^= 0xa9fdca3312;
90 if (c0 & 4) c ^= 0x1bab10e32d;
91 if (c0 & 8) c ^= 0x3706b1677a;
92 if (c0 & 16) c ^= 0x644d626ffd;
111 static std::string INPUT_CHARSET =
112 "0123456789()[],'/*abcdefgh@:$%{}"
113 "IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~"
114 "ijklmnopqrstuvwxyzABCDEFGH`#\"\\ ";
117 static std::string CHECKSUM_CHARSET =
"qpzry9x8gf2tvdw0s3jn54khce6mua7l";
122 for (
auto ch : span) {
123 auto pos = INPUT_CHARSET.find(ch);
124 if (pos == std::string::npos)
return "";
126 cls = cls * 3 + (pos >> 5);
127 if (++clscount == 3) {
134 if (clscount > 0) c =
PolyMod(c, cls);
135 for (
int j = 0; j < 8; ++j) c =
PolyMod(c, 0);
138 std::string ret(8,
' ');
139 for (
int j = 0; j < 8; ++j) ret[j] = CHECKSUM_CHARSET[(c >> (5 * (7 - j))) & 31];
143 std::string AddChecksum(
const std::string& str) {
return str +
"#" + DescriptorChecksum(str); }
149 typedef std::vector<uint32_t> KeyPath;
152 struct PubkeyProvider
157 uint32_t m_expr_index;
160 explicit PubkeyProvider(uint32_t exp_index) : m_expr_index(exp_index) {}
162 virtual ~PubkeyProvider() =
default;
172 virtual bool IsRange()
const = 0;
175 virtual size_t GetSize()
const = 0;
178 virtual std::string
ToString()
const = 0;
181 virtual bool ToPrivateString(
const SigningProvider& arg, std::string& out)
const = 0;
190 class OriginPubkeyProvider final :
public PubkeyProvider
193 std::unique_ptr<PubkeyProvider> m_provider;
195 std::string OriginString()
const
201 OriginPubkeyProvider(uint32_t exp_index,
KeyOriginInfo info, std::unique_ptr<PubkeyProvider> provider) : PubkeyProvider(exp_index), m_origin(
std::move(info)), m_provider(
std::move(provider)) {}
204 if (!m_provider->GetPubKey(pos, arg, key, info, read_cache, write_cache))
return false;
205 std::copy(std::begin(m_origin.fingerprint), std::end(m_origin.fingerprint), info.
fingerprint);
206 info.
path.insert(info.
path.begin(), m_origin.path.begin(), m_origin.path.end());
209 bool IsRange()
const override {
return m_provider->IsRange(); }
210 size_t GetSize()
const override {
return m_provider->GetSize(); }
211 std::string
ToString()
const override {
return "[" + OriginString() +
"]" + m_provider->ToString(); }
212 bool ToPrivateString(
const SigningProvider& arg, std::string& ret)
const override
215 if (!m_provider->ToPrivateString(arg, sub))
return false;
216 ret =
"[" + OriginString() +
"]" + std::move(sub);
222 if (!m_provider->ToNormalizedString(arg, sub, cache))
return false;
228 ret =
"[" + OriginString() + std::move(sub);
230 ret =
"[" + OriginString() +
"]" + std::move(sub);
236 return m_provider->GetPrivKey(pos, arg, key);
241 class ConstPubkeyProvider final :
public PubkeyProvider
247 ConstPubkeyProvider(uint32_t exp_index,
const CPubKey& pubkey,
bool xonly) : PubkeyProvider(exp_index), m_pubkey(pubkey), m_xonly(xonly) {}
252 CKeyID keyid = m_pubkey.GetID();
256 bool IsRange()
const override {
return false; }
257 size_t GetSize()
const override {
return m_pubkey.size(); }
258 std::string
ToString()
const override {
return m_xonly ?
HexStr(m_pubkey).substr(2) :
HexStr(m_pubkey); }
259 bool ToPrivateString(
const SigningProvider& arg, std::string& ret)
const override
262 if (!arg.
GetKey(m_pubkey.GetID(), key))
return false;
273 return arg.
GetKey(m_pubkey.GetID(), key);
277 enum class DeriveType {
284 class BIP32PubkeyProvider final :
public PubkeyProvider
294 if (!arg.
GetKey(m_root_extkey.pubkey.GetID(), key))
return false;
295 ret.
nDepth = m_root_extkey.nDepth;
297 ret.
nChild = m_root_extkey.nChild;
306 if (!GetExtKey(arg, xprv))
return false;
307 for (
auto entry : m_path) {
310 last_hardened = xprv;
316 bool IsHardened()
const
318 if (m_derive == DeriveType::HARDENED)
return true;
319 for (
auto entry : m_path) {
320 if (entry >> 31)
return true;
326 BIP32PubkeyProvider(uint32_t exp_index,
const CExtPubKey& extkey, KeyPath path, DeriveType derive) : PubkeyProvider(exp_index), m_root_extkey(extkey), m_path(
std::move(path)), m_derive(derive) {}
327 bool IsRange()
const override {
return m_derive != DeriveType::NO; }
328 size_t GetSize()
const override {
return 33; }
333 CKeyID keyid = m_root_extkey.pubkey.GetID();
335 parent_info.
path = m_path;
339 if (m_derive == DeriveType::UNHARDENED) final_info_out_tmp.
path.push_back((uint32_t)pos);
340 if (m_derive == DeriveType::HARDENED) final_info_out_tmp.
path.push_back(((uint32_t)pos) | 0x80000000L);
348 if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
349 if (m_derive == DeriveType::HARDENED)
return false;
351 if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey))
return false;
352 final_extkey = parent_extkey;
353 if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.
Derive(final_extkey, pos);
355 }
else if (IsHardened()) {
358 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return false;
359 parent_extkey = xprv.
Neuter();
360 if (m_derive == DeriveType::UNHARDENED) der = xprv.
Derive(xprv, pos);
361 if (m_derive == DeriveType::HARDENED) der = xprv.
Derive(xprv, pos | 0x80000000UL);
362 final_extkey = xprv.
Neuter();
364 last_hardened_extkey = lh_xprv.
Neuter();
367 for (
auto entry : m_path) {
368 der = parent_extkey.
Derive(parent_extkey, entry);
371 final_extkey = parent_extkey;
372 if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.
Derive(final_extkey, pos);
373 assert(m_derive != DeriveType::HARDENED);
377 final_info_out = final_info_out_tmp;
378 key_out = final_extkey.
pubkey;
382 if (m_derive != DeriveType::HARDENED) {
383 write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
386 write_cache->CacheLastHardenedExtPubKey(m_expr_index, last_hardened_extkey);
388 }
else if (final_info_out.
path.size() > 0) {
389 write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey);
395 std::string
ToString()
const override
400 if (m_derive == DeriveType::HARDENED) ret +=
'\'';
404 bool ToPrivateString(
const SigningProvider& arg, std::string& out)
const override
407 if (!GetExtKey(arg, key))
return false;
411 if (m_derive == DeriveType::HARDENED) out +=
'\'';
418 if (m_derive == DeriveType::HARDENED) {
423 int i = (int)m_path.size() - 1;
424 for (; i >= 0; --i) {
425 if (m_path.at(i) >> 31) {
437 for (;
k <= i; ++
k) {
439 origin.
path.push_back(m_path.at(
k));
443 for (;
k < (int)m_path.size(); ++
k) {
444 end_path.push_back(m_path.at(
k));
447 CKeyID id = m_root_extkey.pubkey.GetID();
448 std::copy(
id.begin(),
id.begin() + 4, origin.
fingerprint);
453 if (cache !=
nullptr) {
459 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return false;
469 assert(m_derive == DeriveType::UNHARDENED);
477 if (!GetDerivedExtKey(arg, extkey, dummy))
return false;
478 if (m_derive == DeriveType::UNHARDENED) extkey.
Derive(extkey, pos);
479 if (m_derive == DeriveType::HARDENED) extkey.
Derive(extkey, pos | 0x80000000UL);
489 const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args;
491 const std::string m_name;
498 const std::vector<std::unique_ptr<DescriptorImpl>> m_subdescriptor_args;
501 virtual std::string ToStringExtra()
const {
return ""; }
516 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys,
const std::string&
name) : m_pubkey_args(
std::move(pubkeys)), m_name(
name), m_subdescriptor_args() {}
517 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))) {}
518 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)) {}
520 enum class StringType
529 for (
const auto& arg : m_subdescriptor_args) {
530 if (!arg->IsSolvable())
return false;
537 for (
const auto& pubkey : m_pubkey_args) {
538 if (pubkey->IsRange())
return true;
540 for (
const auto& arg : m_subdescriptor_args) {
541 if (arg->IsRange())
return true;
546 virtual bool ToStringSubScriptHelper(
const SigningProvider* arg, std::string& ret,
const StringType type,
const DescriptorCache* cache =
nullptr)
const
549 for (
const auto& scriptarg : m_subdescriptor_args) {
550 if (pos++) ret +=
",";
552 if (!scriptarg->ToStringHelper(arg, tmp, type, cache))
return false;
553 ret += std::move(tmp);
560 std::string extra = ToStringExtra();
561 size_t pos = extra.size() > 0 ? 1 : 0;
562 std::string ret = m_name +
"(" + extra;
563 for (
const auto& pubkey : m_pubkey_args) {
564 if (pos++) ret +=
",";
567 case StringType::NORMALIZED:
568 if (!pubkey->ToNormalizedString(*arg, tmp, cache))
return false;
570 case StringType::PRIVATE:
571 if (!pubkey->ToPrivateString(*arg, tmp))
return false;
573 case StringType::PUBLIC:
574 tmp = pubkey->ToString();
577 ret += std::move(tmp);
579 std::string subscript;
580 if (!ToStringSubScriptHelper(arg, subscript, type, cache))
return false;
581 if (pos && subscript.size()) ret +=
',';
582 out = std::move(ret) + std::move(subscript) +
")";
589 ToStringHelper(
nullptr, ret, StringType::PUBLIC);
590 return AddChecksum(ret);
595 bool ret = ToStringHelper(&arg, out, StringType::PRIVATE);
596 out = AddChecksum(out);
602 bool ret = ToStringHelper(&arg, out, StringType::NORMALIZED, cache);
603 out = AddChecksum(out);
609 std::vector<std::pair<CPubKey, KeyOriginInfo>> entries;
610 entries.reserve(m_pubkey_args.size());
613 for (
const auto& p : m_pubkey_args) {
614 entries.emplace_back();
615 if (!p->GetPubKey(pos, arg, entries.back().first, entries.back().second, read_cache, write_cache))
return false;
617 std::vector<CScript> subscripts;
619 for (
const auto& subarg : m_subdescriptor_args) {
620 std::vector<CScript> outscripts;
621 if (!subarg->ExpandHelper(pos, arg, read_cache, outscripts, subprovider, write_cache))
return false;
622 assert(outscripts.size() == 1);
623 subscripts.emplace_back(std::move(outscripts[0]));
625 out =
Merge(std::move(out), std::move(subprovider));
627 std::vector<CPubKey> pubkeys;
628 pubkeys.reserve(entries.size());
629 for (
auto& entry : entries) {
630 pubkeys.push_back(entry.first);
631 out.
origins.emplace(entry.first.GetID(), std::make_pair<CPubKey, KeyOriginInfo>(
CPubKey(entry.first), std::move(entry.second)));
634 output_scripts = MakeScripts(pubkeys,
Span{subscripts}, out);
640 return ExpandHelper(pos, provider,
nullptr, output_scripts, out, write_cache);
650 for (
const auto& p : m_pubkey_args) {
652 if (!p->GetPrivKey(pos, provider, key))
continue;
655 for (
const auto& arg : m_subdescriptor_args) {
656 arg->ExpandPrivate(pos, provider, out);
660 std::optional<OutputType>
GetOutputType()
const override {
return std::nullopt; }
664 class AddressDescriptor final :
public DescriptorImpl
668 std::string ToStringExtra()
const override {
return EncodeDestination(m_destination); }
671 AddressDescriptor(
CTxDestination destination) : DescriptorImpl({},
"addr"), m_destination(std::move(destination)) {}
672 bool IsSolvable() const final {
return false; }
674 std::optional<OutputType> GetOutputType()
const override
678 bool IsSingleType() const final {
return true; }
682 class RawDescriptor final :
public DescriptorImpl
686 std::string ToStringExtra()
const override {
return HexStr(m_script); }
689 RawDescriptor(
CScript script) : DescriptorImpl({},
"raw"), m_script(std::move(script)) {}
690 bool IsSolvable() const final {
return false; }
692 std::optional<OutputType> GetOutputType()
const override
698 bool IsSingleType() const final {
return true; }
702 class PKDescriptor final :
public DescriptorImpl
711 return Vector(std::move(script));
717 PKDescriptor(std::unique_ptr<PubkeyProvider> prov,
bool xonly =
false) : DescriptorImpl(
Vector(
std::move(prov)),
"pk"), m_xonly(xonly) {}
718 bool IsSingleType() const final {
return true; }
722 class PKHDescriptor final :
public DescriptorImpl
727 CKeyID id = keys[0].GetID();
728 out.
pubkeys.emplace(
id, keys[0]);
732 PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"pkh") {}
733 std::optional<OutputType> GetOutputType()
const override {
return OutputType::LEGACY; }
734 bool IsSingleType() const final {
return true; }
738 class WPKHDescriptor final :
public DescriptorImpl
743 CKeyID id = keys[0].GetID();
744 out.
pubkeys.emplace(
id, keys[0]);
748 WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"wpkh") {}
749 std::optional<OutputType> GetOutputType()
const override {
return OutputType::BECH32; }
750 bool IsSingleType() const final {
return true; }
754 class ComboDescriptor final :
public DescriptorImpl
759 std::vector<CScript> ret;
760 CKeyID id = keys[0].GetID();
761 out.
pubkeys.emplace(
id, keys[0]);
764 if (keys[0].IsCompressed()) {
767 ret.emplace_back(p2wpkh);
773 ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"combo") {}
774 bool IsSingleType() const final {
return false; }
778 class MultisigDescriptor final :
public DescriptorImpl
780 const int m_threshold;
783 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
786 std::vector<CPubKey> sorted_keys(keys);
787 std::sort(sorted_keys.begin(), sorted_keys.end());
793 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) {}
794 bool IsSingleType() const final {
return true; }
798 class SHDescriptor final :
public DescriptorImpl
808 SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"sh") {}
810 std::optional<OutputType> GetOutputType()
const override
812 assert(m_subdescriptor_args.size() == 1);
816 bool IsSingleType() const final {
return true; }
820 class WSHDescriptor final :
public DescriptorImpl
830 WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"wsh") {}
831 std::optional<OutputType> GetOutputType()
const override {
return OutputType::BECH32; }
832 bool IsSingleType() const final {
return true; }
836 class TRDescriptor final :
public DescriptorImpl
838 std::vector<int> m_depths;
844 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
850 if (!xpk.IsFullyValid())
return {};
854 out.
pubkeys.emplace(keys[0].GetID(), keys[0]);
857 bool ToStringSubScriptHelper(
const SigningProvider* arg, std::string& ret,
const StringType type,
const DescriptorCache* cache =
nullptr)
const override
859 if (m_depths.empty())
return true;
860 std::vector<bool> path;
861 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
863 while ((
int)path.size() <= m_depths[pos]) {
864 if (path.size()) ret +=
'{';
865 path.push_back(
false);
868 if (!m_subdescriptor_args[pos]->ToStringHelper(arg, tmp, type, cache))
return false;
869 ret += std::move(tmp);
870 while (!path.empty() && path.back()) {
871 if (path.size() > 1) ret +=
'}';
874 if (!path.empty()) path.back() =
true;
879 TRDescriptor(std::unique_ptr<PubkeyProvider> internal_key, std::vector<std::unique_ptr<DescriptorImpl>> descs, std::vector<int> depths) :
880 DescriptorImpl(
Vector(
std::move(internal_key)),
std::move(descs),
"tr"), m_depths(
std::move(depths))
882 assert(m_subdescriptor_args.size() == m_depths.size());
885 bool IsSingleType() const final {
return true; }
892 enum class ParseScriptContext {
901 [[nodiscard]]
bool ParseKeyPath(
const std::vector<
Span<const char>>& split, KeyPath& out, std::string&
error)
903 for (
size_t i = 1; i < split.size(); ++i) {
905 bool hardened =
false;
906 if (elem.
size() > 0 && (elem[elem.
size() - 1] ==
'\'' || elem[elem.
size() - 1] ==
'h')) {
914 }
else if (p > 0x7FFFFFFFUL) {
918 out.push_back(p | (((uint32_t)hardened) << 31));
928 bool permit_uncompressed =
ctx == ParseScriptContext::TOP ||
ctx == ParseScriptContext::P2SH;
929 auto split =
Split(sp,
'/');
930 std::string str(split[0].begin(), split[0].end());
931 if (str.size() == 0) {
932 error =
"No key provided";
935 if (split.size() == 1) {
937 std::vector<unsigned char> data =
ParseHex(str);
939 if (pubkey.IsFullyValid()) {
940 if (permit_uncompressed || pubkey.IsCompressed()) {
941 return std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
false);
943 error =
"Uncompressed keys are not allowed";
946 }
else if (data.size() == 32 &&
ctx == ParseScriptContext::P2TR) {
947 unsigned char fullkey[33] = {0x02};
948 std::copy(data.begin(), data.end(), fullkey + 1);
949 pubkey.Set(std::begin(fullkey), std::end(fullkey));
950 if (pubkey.IsFullyValid()) {
951 return std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
true);
962 return std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
ctx == ParseScriptContext::P2TR);
964 error =
"Uncompressed keys are not allowed";
976 DeriveType type = DeriveType::NO;
977 if (split.back() ==
Span{
"*"}.
first(1)) {
979 type = DeriveType::UNHARDENED;
980 }
else if (split.back() ==
Span{
"*'"}.
first(2) || split.back() ==
Span{
"*h"}.
first(2)) {
982 type = DeriveType::HARDENED;
984 if (!ParseKeyPath(split, path,
error))
return nullptr;
986 extpubkey = extkey.
Neuter();
989 return std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type);
997 auto origin_split =
Split(sp,
']');
998 if (origin_split.size() > 2) {
999 error =
"Multiple ']' characters found for a single pubkey";
1002 if (origin_split.size() == 1)
return ParsePubkeyInner(key_exp_index, origin_split[0],
ctx, out,
error);
1003 if (origin_split[0].empty() || origin_split[0][0] !=
'[') {
1004 error =
strprintf(
"Key origin start '[ character expected but not found, got '%c' instead",
1005 origin_split[0].empty() ?
']' : origin_split[0][0]);
1008 auto slash_split =
Split(origin_split[0].subspan(1),
'/');
1009 if (slash_split[0].size() != 8) {
1010 error =
strprintf(
"Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
1013 std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
1014 if (!
IsHex(fpr_hex)) {
1018 auto fpr_bytes =
ParseHex(fpr_hex);
1020 static_assert(
sizeof(info.
fingerprint) == 4,
"Fingerprint must be 4 bytes");
1021 assert(fpr_bytes.size() == 4);
1022 std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.
fingerprint);
1023 if (!ParseKeyPath(slash_split, info.
path,
error))
return nullptr;
1024 auto provider = ParsePubkeyInner(key_exp_index, origin_split[1],
ctx, out,
error);
1025 if (!provider)
return nullptr;
1026 return std::make_unique<OriginPubkeyProvider>(key_exp_index, std::move(info), std::move(provider));
1034 auto expr =
Expr(sp);
1035 bool sorted_multi =
false;
1036 if (
Func(
"pk", expr)) {
1037 auto pubkey = ParsePubkey(key_exp_index, expr,
ctx, out,
error);
1038 if (!pubkey)
return nullptr;
1040 return std::make_unique<PKDescriptor>(std::move(pubkey),
ctx == ParseScriptContext::P2TR);
1042 if ((
ctx == ParseScriptContext::TOP ||
ctx == ParseScriptContext::P2SH ||
ctx == ParseScriptContext::P2WSH) &&
Func(
"pkh", expr)) {
1043 auto pubkey = ParsePubkey(key_exp_index, expr,
ctx, out,
error);
1044 if (!pubkey)
return nullptr;
1046 return std::make_unique<PKHDescriptor>(std::move(pubkey));
1047 }
else if (
Func(
"pkh", expr)) {
1048 error =
"Can only have pkh at top level, in sh(), or in wsh()";
1051 if (
ctx == ParseScriptContext::TOP &&
Func(
"combo", expr)) {
1052 auto pubkey = ParsePubkey(key_exp_index, expr,
ctx, out,
error);
1053 if (!pubkey)
return nullptr;
1055 return std::make_unique<ComboDescriptor>(std::move(pubkey));
1056 }
else if (
Func(
"combo", expr)) {
1057 error =
"Can only have combo() at top level";
1060 if ((
ctx == ParseScriptContext::TOP ||
ctx == ParseScriptContext::P2SH ||
ctx == ParseScriptContext::P2WSH) && ((sorted_multi =
Func(
"sortedmulti", expr)) ||
Func(
"multi", expr))) {
1061 auto threshold =
Expr(expr);
1063 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1064 if (!
ParseUInt32(std::string(threshold.begin(), threshold.end()), &thres)) {
1065 error =
strprintf(
"Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
1068 size_t script_size = 0;
1069 while (expr.size()) {
1070 if (!
Const(
",", expr)) {
1074 auto arg =
Expr(expr);
1075 auto pk = ParsePubkey(key_exp_index, arg,
ctx, out,
error);
1076 if (!pk)
return nullptr;
1077 script_size += pk->GetSize() + 1;
1078 providers.emplace_back(std::move(pk));
1084 }
else if (thres < 1) {
1085 error =
strprintf(
"Multisig threshold cannot be %d, must be at least 1", thres);
1087 }
else if (thres > providers.size()) {
1088 error =
strprintf(
"Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
1091 if (
ctx == ParseScriptContext::TOP) {
1092 if (providers.size() > 3) {
1093 error =
strprintf(
"Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
1097 if (
ctx == ParseScriptContext::P2SH) {
1104 return std::make_unique<MultisigDescriptor>(thres, std::move(providers), sorted_multi);
1105 }
else if (
Func(
"sortedmulti", expr) ||
Func(
"multi", expr)) {
1106 error =
"Can only have multi/sortedmulti at top level, in sh(), or in wsh()";
1109 if ((
ctx == ParseScriptContext::TOP ||
ctx == ParseScriptContext::P2SH) &&
Func(
"wpkh", expr)) {
1110 auto pubkey = ParsePubkey(key_exp_index, expr, ParseScriptContext::P2WPKH, out,
error);
1111 if (!pubkey)
return nullptr;
1113 return std::make_unique<WPKHDescriptor>(std::move(pubkey));
1114 }
else if (
Func(
"wpkh", expr)) {
1115 error =
"Can only have wpkh() at top level or inside sh()";
1118 if (
ctx == ParseScriptContext::TOP &&
Func(
"sh", expr)) {
1119 auto desc =
ParseScript(key_exp_index, expr, ParseScriptContext::P2SH, out,
error);
1120 if (!desc || expr.size())
return nullptr;
1121 return std::make_unique<SHDescriptor>(std::move(desc));
1122 }
else if (
Func(
"sh", expr)) {
1123 error =
"Can only have sh() at top level";
1126 if ((
ctx == ParseScriptContext::TOP ||
ctx == ParseScriptContext::P2SH) &&
Func(
"wsh", expr)) {
1127 auto desc =
ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH, out,
error);
1128 if (!desc || expr.size())
return nullptr;
1129 return std::make_unique<WSHDescriptor>(std::move(desc));
1130 }
else if (
Func(
"wsh", expr)) {
1131 error =
"Can only have wsh() at top level or inside sh()";
1134 if (
ctx == ParseScriptContext::TOP &&
Func(
"addr", expr)) {
1137 error =
"Address is not valid";
1140 return std::make_unique<AddressDescriptor>(std::move(dest));
1141 }
else if (
Func(
"addr", expr)) {
1142 error =
"Can only have addr() at top level";
1145 if (
ctx == ParseScriptContext::TOP &&
Func(
"tr", expr)) {
1146 auto arg =
Expr(expr);
1147 auto internal_key = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR, out,
error);
1148 if (!internal_key)
return nullptr;
1150 std::vector<std::unique_ptr<DescriptorImpl>> subscripts;
1151 std::vector<int> depths;
1153 if (!
Const(
",", expr)) {
1160 std::vector<bool> branches;
1165 while (
Const(
"{", expr)) {
1166 branches.push_back(
false);
1173 auto sarg =
Expr(expr);
1174 subscripts.emplace_back(
ParseScript(key_exp_index, sarg, ParseScriptContext::P2TR, out,
error));
1175 if (!subscripts.back())
return nullptr;
1176 depths.push_back(branches.size());
1178 while (branches.size() && branches.back()) {
1179 if (!
Const(
"}", expr)) {
1183 branches.pop_back();
1186 if (branches.size() && !branches.back()) {
1187 if (!
Const(
",", expr)) {
1191 branches.back() =
true;
1193 }
while (branches.size());
1201 return std::make_unique<TRDescriptor>(std::move(internal_key), std::move(subscripts), std::move(depths));
1202 }
else if (
Func(
"tr", expr)) {
1203 error =
"Can only have tr at top level";
1206 if (
ctx == ParseScriptContext::TOP &&
Func(
"raw", expr)) {
1207 std::string str(expr.begin(), expr.end());
1209 error =
"Raw script is not hex";
1213 return std::make_unique<RawDescriptor>(
CScript(bytes.begin(), bytes.end()));
1214 }
else if (
Func(
"raw", expr)) {
1215 error =
"Can only have raw() at top level";
1218 if (
ctx == ParseScriptContext::P2SH) {
1219 error =
"A function is needed within P2SH";
1221 }
else if (
ctx == ParseScriptContext::P2WSH) {
1222 error =
"A function is needed within P2WSH";
1225 error =
strprintf(
"'%s' is not a valid descriptor function", std::string(expr.begin(), expr.end()));
1229 std::unique_ptr<PubkeyProvider> InferPubkey(
const CPubKey& pubkey, ParseScriptContext,
const SigningProvider& provider)
1231 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
false);
1234 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider));
1236 return key_provider;
1242 std::copy(xkey.
begin(), xkey.
end(), full_key + 1);
1244 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
true);
1247 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider));
1249 return key_provider;
1252 std::unique_ptr<DescriptorImpl> InferScript(
const CScript& script, ParseScriptContext
ctx,
const SigningProvider& provider)
1254 if (
ctx == ParseScriptContext::P2TR && script.
size() == 34 && script[0] == 32 && script[33] ==
OP_CHECKSIG) {
1256 return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key,
ctx, provider));
1259 std::vector<std::vector<unsigned char>> data;
1262 if (txntype ==
TxoutType::PUBKEY && (
ctx == ParseScriptContext::TOP ||
ctx == ParseScriptContext::P2SH ||
ctx == ParseScriptContext::P2WSH)) {
1265 return std::make_unique<PKDescriptor>(InferPubkey(pubkey,
ctx, provider));
1268 if (txntype ==
TxoutType::PUBKEYHASH && (
ctx == ParseScriptContext::TOP ||
ctx == ParseScriptContext::P2SH ||
ctx == ParseScriptContext::P2WSH)) {
1272 if (provider.
GetPubKey(keyid, pubkey)) {
1273 return std::make_unique<PKHDescriptor>(InferPubkey(pubkey,
ctx, provider));
1280 if (provider.
GetPubKey(keyid, pubkey)) {
1281 return std::make_unique<WPKHDescriptor>(InferPubkey(pubkey,
ctx, provider));
1284 if (txntype ==
TxoutType::MULTISIG && (
ctx == ParseScriptContext::TOP ||
ctx == ParseScriptContext::P2SH ||
ctx == ParseScriptContext::P2WSH)) {
1285 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1286 for (
size_t i = 1; i + 1 < data.size(); ++i) {
1288 providers.push_back(InferPubkey(pubkey,
ctx, provider));
1290 return std::make_unique<MultisigDescriptor>((
int)data[0][0], std::move(providers));
1296 if (provider.
GetCScript(scriptid, subscript)) {
1297 auto sub = InferScript(subscript, ParseScriptContext::P2SH, provider);
1298 if (sub)
return std::make_unique<SHDescriptor>(std::move(sub));
1305 if (provider.
GetCScript(scriptid, subscript)) {
1306 auto sub = InferScript(subscript, ParseScriptContext::P2WSH, provider);
1307 if (sub)
return std::make_unique<WSHDescriptor>(std::move(sub));
1313 std::copy(data[0].begin(), data[0].end(), pubkey.
begin());
1322 std::vector<std::unique_ptr<DescriptorImpl>> subscripts;
1323 std::vector<int> depths;
1324 for (
const auto& [depth, script, leaf_ver] : *tree) {
1325 std::unique_ptr<DescriptorImpl> subdesc;
1327 subdesc = InferScript(script, ParseScriptContext::P2TR, provider);
1333 subscripts.push_back(std::move(subdesc));
1334 depths.push_back(depth);
1338 auto key = InferXOnlyPubkey(tap.
internal_key, ParseScriptContext::P2TR, provider);
1339 return std::make_unique<TRDescriptor>(std::move(key), std::move(subscripts), std::move(depths));
1348 return std::make_unique<AddressDescriptor>(std::move(dest));
1352 return std::make_unique<RawDescriptor>(script);
1363 auto check_split =
Split(sp,
'#');
1364 if (check_split.size() > 2) {
1365 error =
"Multiple '#' symbols";
1368 if (check_split.size() == 1 && require_checksum){
1369 error =
"Missing checksum";
1372 if (check_split.size() == 2) {
1373 if (check_split[1].size() != 8) {
1374 error =
strprintf(
"Expected 8 character checksum, not %u characters", check_split[1].size());
1378 auto checksum = DescriptorChecksum(check_split[0]);
1379 if (checksum.empty()) {
1380 error =
"Invalid characters in payload";
1383 if (check_split.size() == 2) {
1384 if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
1385 error =
strprintf(
"Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
1389 if (out_checksum) *out_checksum = std::move(checksum);
1390 sp = check_split[0];
1398 uint32_t key_exp_index = 0;
1399 auto ret =
ParseScript(key_exp_index, sp, ParseScriptContext::TOP, out,
error);
1400 if (sp.
size() == 0 && ret)
return std::unique_ptr<Descriptor>(std::move(ret));
1415 return InferScript(script, ParseScriptContext::TOP, provider);
1426 xpubs[der_index] = xpub;
1446 const auto& der_it = key_exp_it->second.find(der_index);
1447 if (der_it == key_exp_it->second.end())
return false;
1448 xpub = der_it->second;
1466 if (xpub != parent_xpub_pair.second) {
1467 throw std::runtime_error(std::string(__func__) +
": New cached parent xpub does not match already cached parent xpub");
1475 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
1478 if (xpub != derived_xpub_pair.second) {
1479 throw std::runtime_error(std::string(__func__) +
": New cached derived xpub does not match already cached derived xpub");
1483 CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
1484 diff.
CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
1490 if (xpub != lh_xpub_pair.second) {
1491 throw std::runtime_error(std::string(__func__) +
": New cached last hardened xpub does not match already cached last hardened xpub");