mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-25 02:33:24 -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.
|
- `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.
|
- `addr(ADDR)` (top level only): the script which ADDR expands to.
|
||||||
- `raw(HEX)` (top level only): the script whose hex encoding is HEX.
|
- `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:
|
`KEY` expressions:
|
||||||
- Optionally, key origin information, consisting of:
|
- 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:
|
- 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).
|
- 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 `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.
|
- [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)).
|
- `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.
|
- Followed by zero or more `/NUM` unhardened and `/NUM'` hardened BIP32 derivation steps.
|
||||||
|
|
|
@ -1015,6 +1015,24 @@ public:
|
||||||
bool IsSingleType() const final { return true; }
|
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 //
|
// 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";
|
error = "Can only have tr at top level";
|
||||||
return nullptr;
|
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)) {
|
if (ctx == ParseScriptContext::TOP && Func("raw", expr)) {
|
||||||
std::string str(expr.begin(), expr.end());
|
std::string str(expr.begin(), expr.end());
|
||||||
if (!IsHex(str)) {
|
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) {
|
if (ctx == ParseScriptContext::P2WSH) {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
{
|
{
|
||||||
"asm": "1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
|
"asm": "1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
|
||||||
"address": "bcrt1pamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhqz6nvlh",
|
"address": "bcrt1pamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhqz6nvlh",
|
||||||
"desc": "addr(bcrt1pamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhqz6nvlh)#v52jnujz",
|
"desc": "rawtr(eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee)#jk7c6kys",
|
||||||
"type": "witness_v1_taproot"
|
"type": "witness_v1_taproot"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
Loading…
Add table
Reference in a new issue