83 uint64_t PolyMod(uint64_t c,
int val)
86 c = ((c & 0x7ffffffff) << 5) ^ val;
87 if (c0 & 1) c ^= 0xf5dee51989;
88 if (c0 & 2) c ^= 0xa9fdca3312;
89 if (c0 & 4) c ^= 0x1bab10e32d;
90 if (c0 & 8) c ^= 0x3706b1677a;
91 if (c0 & 16) c ^= 0x644d626ffd;
110 static std::string INPUT_CHARSET =
111 "0123456789()[],'/*abcdefgh@:$%{}"
112 "IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~"
113 "ijklmnopqrstuvwxyzABCDEFGH`#\"\\ ";
116 static std::string CHECKSUM_CHARSET =
"qpzry9x8gf2tvdw0s3jn54khce6mua7l";
121 for (
auto ch : span) {
122 auto pos = INPUT_CHARSET.find(ch);
123 if (pos == std::string::npos)
return "";
124 c = PolyMod(c, pos & 31);
125 cls = cls * 3 + (pos >> 5);
126 if (++clscount == 3) {
133 if (clscount > 0) c = PolyMod(c, cls);
134 for (
int j = 0; j < 8; ++j) c = PolyMod(c, 0);
137 std::string ret(8,
' ');
138 for (
int j = 0; j < 8; ++j) ret[j] = CHECKSUM_CHARSET[(c >> (5 * (7 - j))) & 31];
142 std::string AddChecksum(
const std::string& str) {
return str +
"#" + DescriptorChecksum(str); }
148 typedef std::vector<uint32_t> KeyPath;
151 struct PubkeyProvider
156 uint32_t m_expr_index;
159 PubkeyProvider(uint32_t exp_index) : m_expr_index(exp_index) {}
161 virtual ~PubkeyProvider() =
default;
171 virtual bool IsRange()
const = 0;
174 virtual size_t GetSize()
const = 0;
177 virtual std::string
ToString()
const = 0;
180 virtual bool ToPrivateString(
const SigningProvider& arg, std::string& out)
const = 0;
186 class OriginPubkeyProvider final :
public PubkeyProvider
189 std::unique_ptr<PubkeyProvider> m_provider;
191 std::string OriginString()
const
197 OriginPubkeyProvider(uint32_t exp_index,
KeyOriginInfo info, std::unique_ptr<PubkeyProvider> provider) : PubkeyProvider(exp_index), m_origin(std::move(info)), m_provider(std::move(provider)) {}
200 if (!m_provider->GetPubKey(pos, arg, key, info, read_cache, write_cache))
return false;
201 std::copy(std::begin(m_origin.fingerprint), std::end(m_origin.fingerprint), info.
fingerprint);
202 info.
path.insert(info.
path.begin(), m_origin.path.begin(), m_origin.path.end());
205 bool IsRange()
const override {
return m_provider->IsRange(); }
206 size_t GetSize()
const override {
return m_provider->GetSize(); }
207 std::string
ToString()
const override {
return "[" + OriginString() +
"]" + m_provider->ToString(); }
208 bool ToPrivateString(
const SigningProvider& arg, std::string& ret)
const override
211 if (!m_provider->ToPrivateString(arg, sub))
return false;
212 ret =
"[" + OriginString() +
"]" + std::move(sub);
217 return m_provider->GetPrivKey(pos, arg, key);
222 class ConstPubkeyProvider final :
public PubkeyProvider
227 ConstPubkeyProvider(uint32_t exp_index,
const CPubKey& pubkey) : PubkeyProvider(exp_index), m_pubkey(pubkey) {}
232 CKeyID keyid = m_pubkey.GetID();
236 bool IsRange()
const override {
return false; }
237 size_t GetSize()
const override {
return m_pubkey.size(); }
238 std::string
ToString()
const override {
return HexStr(m_pubkey); }
239 bool ToPrivateString(
const SigningProvider& arg, std::string& ret)
const override
242 if (!arg.
GetKey(m_pubkey.GetID(), key))
return false;
248 return arg.
GetKey(m_pubkey.GetID(), key);
252 enum class DeriveType {
259 class BIP32PubkeyProvider final :
public PubkeyProvider
272 if (!arg.
GetKey(m_root_extkey.pubkey.GetID(), key))
return false;
273 ret.
nDepth = m_root_extkey.nDepth;
275 ret.
nChild = m_root_extkey.nChild;
284 if (!GetExtKey(arg, xprv))
return false;
285 for (
auto entry : m_path) {
291 bool IsHardened()
const
293 if (m_derive == DeriveType::HARDENED)
return true;
294 for (
auto entry : m_path) {
295 if (entry >> 31)
return true;
301 BIP32PubkeyProvider(uint32_t exp_index,
const CExtPubKey& extkey, KeyPath path, DeriveType derive) : PubkeyProvider(exp_index), m_root_extkey(extkey), m_path(std::move(path)), m_derive(derive) {}
302 bool IsRange()
const override {
return m_derive != DeriveType::NO; }
303 size_t GetSize()
const override {
return 33; }
308 CKeyID keyid = m_root_extkey.pubkey.GetID();
310 parent_info.
path = m_path;
314 if (m_derive == DeriveType::UNHARDENED) final_info_out_tmp.
path.push_back((uint32_t)pos);
315 if (m_derive == DeriveType::HARDENED) final_info_out_tmp.
path.push_back(((uint32_t)pos) | 0x80000000L);
322 if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
323 if (m_derive == DeriveType::HARDENED)
return false;
325 if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey))
return false;
326 final_extkey = parent_extkey;
327 if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.
Derive(final_extkey, pos);
329 }
else if (m_cached_xpub.
pubkey.
IsValid() && m_derive != DeriveType::HARDENED) {
330 parent_extkey = final_extkey = m_cached_xpub;
331 if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.
Derive(final_extkey, pos);
332 }
else if (IsHardened()) {
334 if (!GetDerivedExtKey(arg, xprv))
return false;
335 parent_extkey = xprv.
Neuter();
336 if (m_derive == DeriveType::UNHARDENED) der = xprv.
Derive(xprv, pos);
337 if (m_derive == DeriveType::HARDENED) der = xprv.
Derive(xprv, pos | 0x80000000UL);
338 final_extkey = xprv.
Neuter();
340 for (
auto entry : m_path) {
341 der = parent_extkey.
Derive(parent_extkey, entry);
344 final_extkey = parent_extkey;
345 if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.
Derive(final_extkey, pos);
346 assert(m_derive != DeriveType::HARDENED);
350 final_info_out = final_info_out_tmp;
351 key_out = final_extkey.
pubkey;
356 if (!m_cached_xpub.
pubkey.
IsValid()) m_cached_xpub = parent_extkey;
360 if (m_derive != DeriveType::HARDENED) {
361 write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
362 }
else if (final_info_out.
path.size() > 0) {
363 write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey);
369 std::string
ToString()
const override
374 if (m_derive == DeriveType::HARDENED) ret +=
'\'';
378 bool ToPrivateString(
const SigningProvider& arg, std::string& out)
const override
381 if (!GetExtKey(arg, key))
return false;
385 if (m_derive == DeriveType::HARDENED) out +=
'\'';
392 if (!GetDerivedExtKey(arg, extkey))
return false;
393 if (m_derive == DeriveType::UNHARDENED) extkey.
Derive(extkey, pos);
394 if (m_derive == DeriveType::HARDENED) extkey.
Derive(extkey, pos | 0x80000000UL);
404 const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args;
406 const std::string m_name;
412 const std::unique_ptr<DescriptorImpl> m_subdescriptor_arg;
415 virtual std::string ToStringExtra()
const {
return ""; }
428 virtual std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& pubkeys,
const CScript* script,
FlatSigningProvider& out)
const = 0;
431 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, std::unique_ptr<DescriptorImpl> script,
const std::string&
name) : m_pubkey_args(std::move(pubkeys)), m_name(
name), m_subdescriptor_arg(std::move(script)) {}
435 if (m_subdescriptor_arg) {
436 if (!m_subdescriptor_arg->IsSolvable())
return false;
443 for (
const auto& pubkey : m_pubkey_args) {
444 if (pubkey->IsRange())
return true;
446 if (m_subdescriptor_arg) {
447 if (m_subdescriptor_arg->IsRange())
return true;
452 bool ToStringHelper(
const SigningProvider* arg, std::string& out,
bool priv)
const
454 std::string extra = ToStringExtra();
455 size_t pos = extra.size() > 0 ? 1 : 0;
456 std::string ret = m_name +
"(" + extra;
457 for (
const auto& pubkey : m_pubkey_args) {
458 if (pos++) ret +=
",";
461 if (!pubkey->ToPrivateString(*arg, tmp))
return false;
463 tmp = pubkey->ToString();
465 ret += std::move(tmp);
467 if (m_subdescriptor_arg) {
468 if (pos++) ret +=
",";
470 if (!m_subdescriptor_arg->ToStringHelper(arg, tmp, priv))
return false;
471 ret += std::move(tmp);
473 out = std::move(ret) +
")";
480 ToStringHelper(
nullptr, ret,
false);
481 return AddChecksum(ret);
486 bool ret = ToStringHelper(&arg, out,
true);
487 out = AddChecksum(out);
493 std::vector<std::pair<CPubKey, KeyOriginInfo>> entries;
494 entries.reserve(m_pubkey_args.size());
497 for (
const auto& p : m_pubkey_args) {
498 entries.emplace_back();
499 if (!p->GetPubKey(pos, arg, entries.back().first, entries.back().second, read_cache, write_cache))
return false;
501 std::vector<CScript> subscripts;
502 if (m_subdescriptor_arg) {
504 if (!m_subdescriptor_arg->ExpandHelper(pos, arg, read_cache, subscripts, subprovider, write_cache))
return false;
505 out =
Merge(out, subprovider);
508 std::vector<CPubKey> pubkeys;
509 pubkeys.reserve(entries.size());
510 for (
auto& entry : entries) {
511 pubkeys.push_back(entry.first);
512 out.
origins.emplace(entry.first.GetID(), std::make_pair<CPubKey, KeyOriginInfo>(
CPubKey(entry.first), std::move(entry.second)));
514 if (m_subdescriptor_arg) {
515 for (
const auto& subscript : subscripts) {
517 std::vector<CScript> addscripts = MakeScripts(pubkeys, &subscript, out);
518 for (
auto& addscript : addscripts) {
519 output_scripts.push_back(std::move(addscript));
523 output_scripts = MakeScripts(pubkeys,
nullptr, out);
530 return ExpandHelper(pos, provider,
nullptr, output_scripts, out, write_cache);
540 for (
const auto& p : m_pubkey_args) {
542 if (!p->GetPrivKey(pos, provider, key))
continue;
545 if (m_subdescriptor_arg) {
547 m_subdescriptor_arg->ExpandPrivate(pos, provider, subprovider);
548 out =
Merge(out, subprovider);
556 class AddressDescriptor final :
public DescriptorImpl
560 std::string ToStringExtra()
const override {
return EncodeDestination(m_destination); }
563 AddressDescriptor(
CTxDestination destination) : DescriptorImpl({}, {},
"addr"), m_destination(std::move(destination)) {}
564 bool IsSolvable() const final {
return false; }
568 switch (m_destination.which()) {
578 bool IsSingleType() const final {
return true; }
582 class RawDescriptor final :
public DescriptorImpl
586 std::string ToStringExtra()
const override {
return HexStr(m_script); }
589 RawDescriptor(
CScript script) : DescriptorImpl({}, {},
"raw"), m_script(std::move(script)) {}
590 bool IsSolvable() const final {
return false; }
596 switch (dest.which()) {
606 bool IsSingleType() const final {
return true; }
610 class PKDescriptor final :
public DescriptorImpl
615 PKDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(std::move(prov)), {},
"pk") {}
616 bool IsSingleType() const final {
return true; }
620 class PKHDescriptor final :
public DescriptorImpl
625 CKeyID id = keys[0].GetID();
626 out.
pubkeys.emplace(
id, keys[0]);
630 PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(std::move(prov)), {},
"pkh") {}
632 bool IsSingleType() const final {
return true; }
636 class WPKHDescriptor final :
public DescriptorImpl
641 CKeyID id = keys[0].GetID();
642 out.
pubkeys.emplace(
id, keys[0]);
646 WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(std::move(prov)), {},
"wpkh") {}
648 bool IsSingleType() const final {
return true; }
652 class ComboDescriptor final :
public DescriptorImpl
657 std::vector<CScript> ret;
658 CKeyID id = keys[0].GetID();
659 out.
pubkeys.emplace(
id, keys[0]);
662 if (keys[0].IsCompressed()) {
665 ret.emplace_back(p2wpkh);
671 ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(std::move(prov)), {},
"combo") {}
672 bool IsSingleType() const final {
return false; }
676 class MultisigDescriptor final :
public DescriptorImpl
678 const int m_threshold;
681 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
684 std::vector<CPubKey> sorted_keys(keys);
685 std::sort(sorted_keys.begin(), sorted_keys.end());
691 MultisigDescriptor(
int threshold, std::vector<std::unique_ptr<PubkeyProvider>> providers,
bool sorted =
false) : DescriptorImpl(std::move(providers), {}, sorted ?
"sortedmulti" :
"multi"), m_threshold(threshold), m_sorted(sorted) {}
692 bool IsSingleType() const final {
return true; }
696 class SHDescriptor final :
public DescriptorImpl
701 SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"sh") {}
705 assert(m_subdescriptor_arg);
709 bool IsSingleType() const final {
return true; }
713 class WSHDescriptor final :
public DescriptorImpl
718 WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"wsh") {}
720 bool IsSingleType() const final {
return true; }
727 enum class ParseScriptContext {
736 for (
size_t i = 1; i < split.size(); ++i) {
738 bool hardened =
false;
739 if (elem.
size() > 0 && (elem[elem.
size() - 1] ==
'\'' || elem[elem.
size() - 1] ==
'h')) {
747 }
else if (p > 0x7FFFFFFFUL) {
751 out.push_back(p | (((uint32_t)hardened) << 31));
761 auto split =
Split(sp,
'/');
762 std::string str(split[0].begin(), split[0].end());
763 if (str.size() == 0) {
764 error =
"No key provided";
767 if (split.size() == 1) {
769 std::vector<unsigned char> data =
ParseHex(str);
771 if (pubkey.IsFullyValid()) {
772 if (permit_uncompressed || pubkey.IsCompressed()) {
773 return MakeUnique<ConstPubkeyProvider>(key_exp_index, pubkey);
775 error =
"Uncompressed keys are not allowed";
787 return MakeUnique<ConstPubkeyProvider>(key_exp_index, pubkey);
789 error =
"Uncompressed keys are not allowed";
801 DeriveType type = DeriveType::NO;
802 if (split.back() ==
MakeSpan(
"*").first(1)) {
804 type = DeriveType::UNHARDENED;
805 }
else if (split.back() ==
MakeSpan(
"*'").first(2) || split.back() ==
MakeSpan(
"*h").first(2)) {
807 type = DeriveType::HARDENED;
809 if (!ParseKeyPath(split, path,
error))
return nullptr;
811 extpubkey = extkey.
Neuter();
814 return MakeUnique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type);
822 auto origin_split =
Split(sp,
']');
823 if (origin_split.size() > 2) {
824 error =
"Multiple ']' characters found for a single pubkey";
827 if (origin_split.size() == 1)
return ParsePubkeyInner(key_exp_index, origin_split[0], permit_uncompressed, out,
error);
828 if (origin_split[0].empty() || origin_split[0][0] !=
'[') {
829 error =
strprintf(
"Key origin start '[ character expected but not found, got '%c' instead",
830 origin_split[0].empty() ?
']' : origin_split[0][0]);
833 auto slash_split =
Split(origin_split[0].subspan(1),
'/');
834 if (slash_split[0].size() != 8) {
835 error =
strprintf(
"Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
838 std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
839 if (!
IsHex(fpr_hex)) {
845 static_assert(
sizeof(info.
fingerprint) == 4,
"Fingerprint must be 4 bytes");
846 assert(fpr_bytes.size() == 4);
847 std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.
fingerprint);
848 if (!ParseKeyPath(slash_split, info.
path,
error))
return nullptr;
849 auto provider = ParsePubkeyInner(key_exp_index, origin_split[1], permit_uncompressed, out,
error);
850 if (!provider)
return nullptr;
851 return MakeUnique<OriginPubkeyProvider>(key_exp_index, std::move(info), std::move(provider));
859 auto expr =
Expr(sp);
860 bool sorted_multi =
false;
861 if (
Func(
"pk", expr)) {
862 auto pubkey = ParsePubkey(key_exp_index, expr,
ctx != ParseScriptContext::P2WSH, out,
error);
863 if (!pubkey)
return nullptr;
864 return MakeUnique<PKDescriptor>(std::move(pubkey));
866 if (
Func(
"pkh", expr)) {
867 auto pubkey = ParsePubkey(key_exp_index, expr,
ctx != ParseScriptContext::P2WSH, out,
error);
868 if (!pubkey)
return nullptr;
869 return MakeUnique<PKHDescriptor>(std::move(pubkey));
871 if (
ctx == ParseScriptContext::TOP &&
Func(
"combo", expr)) {
872 auto pubkey = ParsePubkey(key_exp_index, expr,
true, out,
error);
873 if (!pubkey)
return nullptr;
874 return MakeUnique<ComboDescriptor>(std::move(pubkey));
875 }
else if (
ctx != ParseScriptContext::TOP &&
Func(
"combo", expr)) {
876 error =
"Cannot have combo in non-top level";
879 if ((sorted_multi =
Func(
"sortedmulti", expr)) ||
Func(
"multi", expr)) {
880 auto threshold =
Expr(expr);
882 std::vector<std::unique_ptr<PubkeyProvider>> providers;
883 if (!
ParseUInt32(std::string(threshold.begin(), threshold.end()), &thres)) {
884 error =
strprintf(
"Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
887 size_t script_size = 0;
888 while (expr.size()) {
889 if (!
Const(
",", expr)) {
893 auto arg =
Expr(expr);
894 auto pk = ParsePubkey(key_exp_index, arg,
ctx != ParseScriptContext::P2WSH, out,
error);
895 if (!pk)
return nullptr;
896 script_size += pk->GetSize() + 1;
897 providers.emplace_back(std::move(pk));
900 if (providers.empty() || providers.size() > 16) {
901 error =
strprintf(
"Cannot have %u keys in multisig; must have between 1 and 16 keys, inclusive", providers.size());
903 }
else if (thres < 1) {
904 error =
strprintf(
"Multisig threshold cannot be %d, must be at least 1", thres);
906 }
else if (thres > providers.size()) {
907 error =
strprintf(
"Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
910 if (
ctx == ParseScriptContext::TOP) {
911 if (providers.size() > 3) {
912 error =
strprintf(
"Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
916 if (
ctx == ParseScriptContext::P2SH) {
922 return MakeUnique<MultisigDescriptor>(thres, std::move(providers), sorted_multi);
924 if (
ctx != ParseScriptContext::P2WSH &&
Func(
"wpkh", expr)) {
925 auto pubkey = ParsePubkey(key_exp_index, expr,
false, out,
error);
926 if (!pubkey)
return nullptr;
927 return MakeUnique<WPKHDescriptor>(std::move(pubkey));
928 }
else if (
ctx == ParseScriptContext::P2WSH &&
Func(
"wpkh", expr)) {
929 error =
"Cannot have wpkh within wsh";
932 if (
ctx == ParseScriptContext::TOP &&
Func(
"sh", expr)) {
933 auto desc =
ParseScript(key_exp_index, expr, ParseScriptContext::P2SH, out,
error);
934 if (!desc || expr.size())
return nullptr;
935 return MakeUnique<SHDescriptor>(std::move(desc));
936 }
else if (
ctx != ParseScriptContext::TOP &&
Func(
"sh", expr)) {
937 error =
"Cannot have sh in non-top level";
940 if (
ctx != ParseScriptContext::P2WSH &&
Func(
"wsh", expr)) {
941 auto desc =
ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH, out,
error);
942 if (!desc || expr.size())
return nullptr;
943 return MakeUnique<WSHDescriptor>(std::move(desc));
944 }
else if (
ctx == ParseScriptContext::P2WSH &&
Func(
"wsh", expr)) {
945 error =
"Cannot have wsh within wsh";
948 if (
ctx == ParseScriptContext::TOP &&
Func(
"addr", expr)) {
951 error =
"Address is not valid";
954 return MakeUnique<AddressDescriptor>(std::move(dest));
956 if (
ctx == ParseScriptContext::TOP &&
Func(
"raw", expr)) {
957 std::string str(expr.begin(), expr.end());
959 error =
"Raw script is not hex";
963 return MakeUnique<RawDescriptor>(
CScript(bytes.begin(), bytes.end()));
965 if (
ctx == ParseScriptContext::P2SH) {
966 error =
"A function is needed within P2SH";
968 }
else if (
ctx == ParseScriptContext::P2WSH) {
969 error =
"A function is needed within P2WSH";
972 error =
strprintf(
"%s is not a valid descriptor function", std::string(expr.begin(), expr.end()));
976 std::unique_ptr<PubkeyProvider> InferPubkey(
const CPubKey& pubkey, ParseScriptContext,
const SigningProvider& provider)
978 std::unique_ptr<PubkeyProvider> key_provider = MakeUnique<ConstPubkeyProvider>(0, pubkey);
981 return MakeUnique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider));
986 std::unique_ptr<DescriptorImpl> InferScript(
const CScript& script, ParseScriptContext
ctx,
const SigningProvider& provider)
988 std::vector<std::vector<unsigned char>> data;
992 CPubKey pubkey(data[0].begin(), data[0].end());
994 return MakeUnique<PKDescriptor>(InferPubkey(pubkey,
ctx, provider));
1001 if (provider.
GetPubKey(keyid, pubkey)) {
1002 return MakeUnique<PKHDescriptor>(InferPubkey(pubkey,
ctx, provider));
1009 if (provider.
GetPubKey(keyid, pubkey)) {
1010 return MakeUnique<WPKHDescriptor>(InferPubkey(pubkey,
ctx, provider));
1014 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1015 for (
size_t i = 1; i + 1 < data.size(); ++i) {
1016 CPubKey pubkey(data[i].begin(), data[i].end());
1017 providers.push_back(InferPubkey(pubkey,
ctx, provider));
1019 return MakeUnique<MultisigDescriptor>((
int)data[0][0], std::move(providers));
1025 if (provider.
GetCScript(scriptid, subscript)) {
1026 auto sub = InferScript(subscript, ParseScriptContext::P2SH, provider);
1027 if (sub)
return MakeUnique<SHDescriptor>(std::move(sub));
1034 if (provider.
GetCScript(scriptid, subscript)) {
1035 auto sub = InferScript(subscript, ParseScriptContext::P2WSH, provider);
1036 if (sub)
return MakeUnique<WSHDescriptor>(std::move(sub));
1043 return MakeUnique<AddressDescriptor>(std::move(dest));
1047 return MakeUnique<RawDescriptor>(script);
1058 auto check_split =
Split(sp,
'#');
1059 if (check_split.size() > 2) {
1060 error =
"Multiple '#' symbols";
1063 if (check_split.size() == 1 && require_checksum){
1064 error =
"Missing checksum";
1067 if (check_split.size() == 2) {
1068 if (check_split[1].size() != 8) {
1069 error =
strprintf(
"Expected 8 character checksum, not %u characters", check_split[1].size());
1073 auto checksum = DescriptorChecksum(check_split[0]);
1074 if (checksum.empty()) {
1075 error =
"Invalid characters in payload";
1078 if (check_split.size() == 2) {
1079 if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
1080 error =
strprintf(
"Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
1084 if (out_checksum) *out_checksum = std::move(checksum);
1085 sp = check_split[0];
1094 if (sp.
size() == 0 && ret)
return std::unique_ptr<Descriptor>(std::move(ret));
1109 return InferScript(script, ParseScriptContext::TOP, provider);
1120 xpubs[der_index] = xpub;
1135 const auto& der_it = key_exp_it->second.find(der_index);
1136 if (der_it == key_exp_it->second.end())
return false;
1137 xpub = der_it->second;
std::string FormatHDKeypath(const std::vector< uint32_t > &path)
An encapsulated private key.
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.
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
A hasher class for RIPEMD-160.
CRIPEMD160 & Write(const unsigned char *data, size_t len)
void Finalize(unsigned char hash[OUTPUT_SIZE])
Serialized script, used inside transaction inputs and outputs.
A reference to a CScript: the Hash160 of its serialization (see script.h)
Cache for single descriptor's derived extended pubkeys.
bool GetCachedParentExtPubKey(uint32_t key_exp_pos, CExtPubKey &xpub) const
Retrieve a cached parent xpub.
void CacheDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, const CExtPubKey &xpub)
Cache an xpub derived at an index.
void CacheParentExtPubKey(uint32_t key_exp_pos, const CExtPubKey &xpub)
Cache a parent 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)
const ExtPubKeyMap GetCachedParentExtPubKeys() const
Retrieve all cached parent xpubs.
const std::unordered_map< uint32_t, ExtPubKeyMap > GetCachedDerivedExtPubKeys() const
Retrieve all cached derived xpubs.
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 GetPubKey(const CKeyID &address, CPubKey &pubkey) const
virtual bool GetKey(const CKeyID &address, CKey &key) const
virtual bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const
A Span is an object that can refer to a contiguous sequence of objects.
constexpr std::size_t size() const noexcept
constexpr C * end() const noexcept
constexpr C * begin() const noexcept
CONSTEXPR_IF_NOT_DEBUG Span< C > first(std::size_t count) const noexcept
CScript ParseScript(const std::string &s)
bool CheckChecksum(Span< const char > &sp, bool require_checksum, std::string &error, std::string *out_checksum=nullptr)
Check a descriptor checksum, and update desc to be the checksum-less part.
std::string GetDescriptorChecksum(const std::string &descriptor)
Get the checksum for a descriptor.
std::unique_ptr< Descriptor > Parse(const std::string &descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible.
std::unordered_map< uint32_t, CExtPubKey > ExtPubKeyMap
std::string EncodeExtKey(const CExtKey &key)
CExtPubKey DecodeExtPubKey(const std::string &str)
std::string EncodeSecret(const CKey &key)
std::string EncodeDestination(const CTxDestination &dest)
CKey DecodeSecret(const std::string &str)
CTxDestination DecodeDestination(const std::string &str)
std::string EncodeExtPubKey(const CExtPubKey &key)
CExtKey DecodeExtKey(const std::string &str)
std::vector< Span< const char > > Split(const Span< const char > &sp, char sep)
Split a string on every instance of sep, returning a vector.
Span< const char > Expr(Span< const char > &sp)
Extract the expression that sp begins with.
bool Const(const std::string &str, Span< const char > &sp)
Parse a constant.
bool Func(const std::string &str, Span< const char > &sp)
Parse a function call.
std::deque< CInv >::iterator it
static auto & nullopt
Substitute for C++17 std::nullopt.
boost::optional< T > Optional
Substitute for C++17 std::optional.
@ TOP
Top-level scriptPubKey.
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
bool IsSolvable(const SigningProvider &provider, const CScript &script)
static bool GetPubKey(const SigningProvider &provider, const SignatureData &sigdata, const CKeyID &address, CPubKey &pubkey)
const SigningProvider & DUMMY_SIGNING_PROVIDER
FlatSigningProvider Merge(const FlatSigningProvider &a, const FlatSigningProvider &b)
constexpr Span< A > MakeSpan(A(&a)[N])
MakeSpan for arrays:
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.
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
boost::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
std::vector< unsigned char > ParseHex(const char *psz)
bool ParseUInt32(const std::string &str, uint32_t *out)
Convert decimal string to unsigned 32-bit integer with strict parse error feedback.
bool IsHex(const std::string &str)
std::string ToString(const T &t)
Locale-independent version of std::to_string.
unsigned char vchFingerprint[4]
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::string ToString() const =0
Convert the descriptor back to a string, undoing parsing.
virtual bool Expand(int pos, const SigningProvider &provider, std::vector< CScript > &output_scripts, FlatSigningProvider &out, DescriptorCache *write_cache=nullptr) const =0
Expand a descriptor at a specified position.
virtual Optional< OutputType > GetOutputType() const =0
virtual bool IsRange() const =0
Whether the expansion of this descriptor depends on the position.
virtual bool IsSolvable() const =0
Whether this descriptor has all information about signing ignoring lack of private keys.
virtual void ExpandPrivate(int pos, const SigningProvider &provider, FlatSigningProvider &out) const =0
Expand the private key for a descriptor at a specified position, if possible.
virtual bool ToPrivateString(const SigningProvider &provider, std::string &out) const =0
Convert the descriptor to a private string.
virtual bool ExpandFromCache(int pos, const DescriptorCache &read_cache, std::vector< CScript > &output_scripts, FlatSigningProvider &out) const =0
Expand a descriptor at a specified position using cached expansion data.
std::map< CKeyID, std::pair< CPubKey, KeyOriginInfo > > origins
std::map< CKeyID, CPubKey > pubkeys
std::map< CKeyID, CKey > keys
std::map< CScriptID, CScript > scripts
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
bool error(const char *fmt, const Args &... args)
static secp256k1_context * ctx
std::vector< typename std::common_type< Args... >::type > Vector(Args &&... args)
Construct a vector with the specified elements.