mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-10 03:47:29 -03:00
Add rawtr() descriptor for P2TR with unknown tweak
This commit is contained in:
parent
5560682a44
commit
8d9670ccb7
3 changed files with 38 additions and 2 deletions
|
@ -77,6 +77,7 @@ Descriptors consist of several types of expressions. The top level expression is
|
|||
- `tr(KEY)` or `tr(KEY,TREE)` (top level only): P2TR output with the specified key as internal key, and optionally a tree of script paths.
|
||||
- `addr(ADDR)` (top level only): the script which ADDR expands to.
|
||||
- `raw(HEX)` (top level only): the script whose hex encoding is HEX.
|
||||
- `rawtr(KEY)` (top level only): P2TR output with the specified key as output key. NOTE: while it's possible to use this to construct wallets, it has several downsides, like being unable to prove no hidden script path exists. Use at your own risk.
|
||||
|
||||
`KEY` expressions:
|
||||
- Optionally, key origin information, consisting of:
|
||||
|
@ -87,7 +88,7 @@ Descriptors consist of several types of expressions. The top level expression is
|
|||
- Followed by the actual key, which is either:
|
||||
- Hex encoded public keys (either 66 characters starting with `02` or `03` for a compressed pubkey, or 130 characters starting with `04` for an uncompressed pubkey).
|
||||
- Inside `wpkh` and `wsh`, only compressed public keys are permitted.
|
||||
- Inside `tr`, x-only pubkeys are also permitted (64 hex characters).
|
||||
- Inside `tr` and `rawtr`, x-only pubkeys are also permitted (64 hex characters).
|
||||
- [WIF](https://en.bitcoin.it/wiki/Wallet_import_format) encoded private keys may be specified instead of the corresponding public key, with the same meaning.
|
||||
- `xpub` encoded extended public key or `xprv` encoded extended private key (as defined in [BIP 32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)).
|
||||
- Followed by zero or more `/NUM` unhardened and `/NUM'` hardened BIP32 derivation steps.
|
||||
|
|
|
@ -1015,6 +1015,24 @@ public:
|
|||
bool IsSingleType() const final { return true; }
|
||||
};
|
||||
|
||||
/** A parsed rawtr(...) descriptor. */
|
||||
class RawTRDescriptor final : public DescriptorImpl
|
||||
{
|
||||
protected:
|
||||
std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript> scripts, FlatSigningProvider& out) const override
|
||||
{
|
||||
assert(keys.size() == 1);
|
||||
XOnlyPubKey xpk(keys[0]);
|
||||
if (!xpk.IsFullyValid()) return {};
|
||||
WitnessV1Taproot output{xpk};
|
||||
return Vector(GetScriptForDestination(output));
|
||||
}
|
||||
public:
|
||||
RawTRDescriptor(std::unique_ptr<PubkeyProvider> output_key) : DescriptorImpl(Vector(std::move(output_key)), "rawtr") {}
|
||||
std::optional<OutputType> GetOutputType() const override { return OutputType::BECH32M; }
|
||||
bool IsSingleType() const final { return true; }
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Parser //
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1453,6 +1471,16 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const
|
|||
error = "Can only have tr at top level";
|
||||
return nullptr;
|
||||
}
|
||||
if (ctx == ParseScriptContext::TOP && Func("rawtr", expr)) {
|
||||
auto arg = Expr(expr);
|
||||
auto output_key = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR, out, error);
|
||||
if (!output_key) return nullptr;
|
||||
++key_exp_index;
|
||||
return std::make_unique<RawTRDescriptor>(std::move(output_key));
|
||||
} else if (Func("rawtr", expr)) {
|
||||
error = "Can only have rawtr at top level";
|
||||
return nullptr;
|
||||
}
|
||||
if (ctx == ParseScriptContext::TOP && Func("raw", expr)) {
|
||||
std::string str(expr.begin(), expr.end());
|
||||
if (!IsHex(str)) {
|
||||
|
@ -1626,6 +1654,13 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo
|
|||
}
|
||||
}
|
||||
}
|
||||
// If the above doesn't work, construct a rawtr() descriptor with just the encoded x-only pubkey.
|
||||
if (pubkey.IsFullyValid()) {
|
||||
auto key = InferXOnlyPubkey(pubkey, ParseScriptContext::P2TR, provider);
|
||||
if (key) {
|
||||
return std::make_unique<RawTRDescriptor>(std::move(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx == ParseScriptContext::P2WSH) {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
{
|
||||
"asm": "1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
|
||||
"address": "bcrt1pamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhqz6nvlh",
|
||||
"desc": "addr(bcrt1pamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhqz6nvlh)#v52jnujz",
|
||||
"desc": "rawtr(eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee)#jk7c6kys",
|
||||
"type": "witness_v1_taproot"
|
||||
}
|
||||
],
|
||||
|
|
Loading…
Reference in a new issue