
Bitcoin Rust
- 4 installs
- 4 repo stars
- Updated February 25, 2026
- hairyf/blockchain-master
Use the rust-bitcoin library for consensus encoding, transactions, scripts, keys, addresses, PSBT, BIP-32, and Taproot in wallets and tooling.
About
A reference for rust-bitcoin covering de/serialization of blocks and transactions, script building, keys/addresses, and PSBT v0. A developer uses it to build Bitcoin wallets, indexers, and tooling in Rust (not consensus validation).
- Transaction/block serialization, script parsing, and BIP-32 keys/addresses
- PSBT v0 support with explicit non-goal of consensus validation
Bitcoin Rust by the numbers
- 4 all-time installs (skills.sh)
- Ranked #347 of 479 Web3 & Blockchain skills by installs in the Skillselion catalog
- Data as of Jul 13, 2026 (Skillselion catalog sync)
npx skills add https://github.com/hairyf/blockchain-master --skill bitcoin-rustAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 4 |
|---|---|
| repo stars | ★ 4 |
| Last updated | February 25, 2026 |
| Repository | hairyf/blockchain-master ↗ |
What it does
Use the rust-bitcoin library for consensus encoding, transactions, scripts, keys, addresses, PSBT, BIP-32, and Taproot in wallets and tooling.
Files
Skill based on rust-bitcoin (rust-bitcoin/rust-bitcoin), generated fromsources/bitcoin-rust. Doc path:sources/bitcoin-rust/docs/, README, and cratelib.rs.
Rust Bitcoin supports the Bitcoin network protocol and primitives: de/serialization of blocks and transactions, script parsing and building, private/public keys and addresses (including BIP-32), and PSBT v0. Use for wallets, indexers, and tooling—not for consensus validation. All content is in English.
Core References
| Topic | Description | Reference |
|---|---|---|
| Overview | What rust-bitcoin is, capabilities, limitations, crate stack, features | core-overview |
| Consensus encoding | Encodable/Decodable, serialize/deserialize, partial and hex helpers | core-consensus-encoding |
| Types and crates | Block, Transaction, Script, Amount, hashes, network; crate layout and versions | core-types-and-crates |
Features
| Topic | Description | Reference |
|---|---|---|
| Addresses | P2PKH, P2WPKH, P2TR, etc.; creation, parsing, network validation | features-addresses |
| Keys and signing | PrivateKey, PublicKey, XOnlyPublicKey, ECDSA/Taproot sighash and signing | features-keys-and-signing |
| PSBT | BIP-0174 PSBT v0; creation, signing, extraction; roles and limits | features-psbt |
| Script | ScriptBuf, builder, opcodes, script pubkey types | features-script |
| BIP-32 | Xpriv, Xpub, derivation paths, PSBT key source | features-bip32 |
| Taproot | Tweaks, TapLeafHash, script tree, P2TR and sighash | features-taproot |
Best Practices
| Topic | Description | Reference |
|---|---|---|
| Coding policy | Imports, re-exports, errors, rustdoc, BIP references | best-practices-policy |
| Dependencies | Policy on adding dependencies; MSRV and unsafe | best-practices-dependencies |
Generation Info
- Source:
sources/bitcoin-rust(https://github.com/rust-bitcoin/rust-bitcoin) - Doc path:
docs/(primary),README.md, and cratelib.rs/ module sources - Git SHA:
3c901337828da5406eba7b0997564705d23f0fe2 - Generated: 2026-02-24
Dependency Policy
The project is averse to new dependencies; a strong case is required. When adding functionality, prefer implementing in-tree unless a dependency clearly wins on the criteria below.
Requirements for new dependencies
- Maintainers are reputable and write idiomatic Rust.
- Quick response to bug reports and constructive response to code-quality PRs.
- Idiomatic, well-documented API; stable or close to stable.
- Conservative MSRV—hard requirement for mandatory dependencies.
- Reasonable performance and test coverage; CI, clippy, fuzzing (and miri where applicable).
- No reckless
unsafe: no large or complex unsafe chunks; no safe-looking functions that can cause UB depending on arguments; prefer safe code when equally fast; safe abstractions where needed.
These apply recursively: the full dependency tree should not pull in significantly more code than needed for the feature.
Reckless unsafe (reject)
- Large or complicated unsafe blocks (e.g. whole module).
- (Private) functions that can cause UB depending on arguments but are not marked
unsafe. - Code that could be written without
unsafewith similar performance. - Missing safe wrappers around unsafe operations.
In practice
Dependencies that fail the above are rejected. After that, discussion centers on: benefit vs niche, past MSRV disagreements, and whether to rely on external unsafe (e.g. ArrayVec) vs in-tree code.
When suggesting or adding a dependency in the rust-bitcoin ecosystem, check MSRV and the dependency tree; prefer minimal, stable, well-maintained crates.
<!-- Source references:
- sources/bitcoin-rust/docs/dependencies.md
-->
Coding Policy (rust-bitcoin)
When contributing or generating code that matches rust-bitcoin style, follow these conventions (from docs/policy.md). Useful for agents that patch or generate code in this repo.
Imports
- Modules first (project structure), then private imports, then public re-exports with
#[rustfmt::skip]and manual sort. - Avoid wildcards except: test modules (
use super::*), enum variants (use LockTime::*), opcodes (use opcodes::all::*). Do not useuse crate::prelude::*. - Use types from the highest crate in scope:
use crate::Foonotunits::Foo(enforced in CI).
Re-exports
- Do not re-export types unless it is clearly helpful. If a type from crate
barappears in the public API of cratefoo,foomustpub extern crate barat root. - For
bitcoin,primitives,units: non-error re-exports usedoc(inline); error re-exports usedoc(no_inline). Errors that are directly in the API are re-exported; others live in anerrorsubmodule.
Return type
- Use
Selfas return type; when constructing the return value useSelfor the type name. In error enums useSelffor variant construction.
Errors
- Prefer
#[non_exhaustive]and private fields. - Derive
Debug, Clone, PartialEq, Eq(andCopyonly if not non_exhaustive). - Use
write_err!()forDisplaywhen wrapping a source error. - Suffix type names with
Error; do not suffix enum variants withError. - Include context (e.g. the invalid string) and return costly input in error when applicable.
- Call
internals::impl_from_infallible!; implementstd::error::Errorwhen public (feature "std"). - Messages in lower case except proper nouns and variable names.
expectmessages: describe why the operation is expected to succeed (precondition style), lower case.
Rustdoc
- Use third person: “Calculates the distance” not “Calculate the distance”.
- Add
# Errorsand# Panicssections where relevant; example code must passjust lint. - Prefer links at the bottom of the doc block (e.g.
[BIP-0341]: <url>). - Reference BIPs as
BIP-XXXX(4-digit with leading zeros), e.g.BIP-0032,BIP-0341. Exceptions: module/function/variable names keep existing style (e.g.bip32,bip_341_tests).
Derives and attributes
- Standard derives when sensible:
Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash. - Use
#[track_caller]on functions that panic on invalid arguments. - Licensing:
// SPDX-License-Identifier: CC0-1.0at file start.
Following this policy keeps patches and generated code consistent with the repository.
<!-- Source references:
- sources/bitcoin-rust/docs/policy.md
-->
Consensus Encoding
Bitcoin data that goes on disk or the network must use the library’s consensus encoding (little-endian, compact size, etc.). Types implement Encodable and Decodable from the bitcoin::consensus module (or io/consensus_encoding in newer stacks).
Serialize / deserialize
use bitcoin::consensus::{deserialize, deserialize_partial, serialize, serialize_hex, Encodable, Decodable};
use bitcoin::Transaction;
// Full buffer consumption required
let tx: Transaction = deserialize(&bytes)?;
let hex_tx: Transaction = bitcoin::consensus::deserialize_hex(hex_str)?;
// Partial: get decoded value and number of bytes consumed
let (tx, consumed) = deserialize_partial(&bytes)?;
// Encode to Vec or hex
let bytes: Vec<u8> = serialize(&tx);
let hex: String = serialize_hex(&tx);Traits
- Encodable:
consensus_encode<W: Write>(&self, w: &mut W) -> Result<usize, io::Error>. - Decodable:
consensus_decode<R: BufRead>(r: &mut R) -> Result<Self, consensus::encode::Error>.
Use these for any type that must match network/disk format (e.g. Block, Transaction, TxIn, TxOut, Script, Amount). For user-facing or RPC data (e.g. big-endian hashes, decoded scripts), use other serialization as appropriate—consensus encoding is specifically for wire/block storage.
Low-level primitives
consensus::encode provides ReadExt/WriteExt style helpers (e.g. emit_u32, read_u32, emit_compact_size) for building custom encoders/decoders. New code in the ecosystem may use the sans-I/O consensus_encoding crate (Encoder/Decoder traits, no direct std::io); see ADR 0001 for the design.
Key points
- Prefer
serialize/deserialize(and_partial/_hex) for standard types. - Consensus encoding is little-endian; variable-length integers use CompactSize.
- Do not use consensus encoding for user-facing hashes (e.g. display); use hex/display traits that match user expectations.
<!-- Source references:
- sources/bitcoin-rust/bitcoin/src/consensus/encode.rs
- sources/bitcoin-rust/docs/adr/0001_consensus_encoding.md
-->
Rust Bitcoin Overview
The rust-bitcoin library supports the Bitcoin network protocol and primitives: de/serialization of blocks and transactions, script parsing, keys and addresses (including BIP-32), and PSBT v0. Use it for wallets, indexers, tooling, and non-consensus Bitcoin applications—not for full consensus validation.
Capabilities
- De/serialization: Bitcoin protocol network messages, blocks, transactions, scripts (consensus encoding via
Encodable/Decodable). - Script: Parsing and building scripts; opcodes; witness and legacy script types.
- Keys and addresses: Private/public keys, WIF, BIP-32 HD keys, P2PKH/P2SH/P2WPKH/P2WSH/P2TR addresses (bech32 and base58).
- PSBT: BIP-0174 Partially Signed Bitcoin Transactions (v0); de/serialization and all roles except Input Finalizer (use rust-miniscript to finalize).
- Taproot: Taproot keys, tweaks, and script extensions.
- No_std: Optional; build with
--no-default-featuresfor embedded. Seebitcoin/embeddedandhashes/embeddedfor examples.
Important limitation
Do not use for consensus. The library must not be used for fully validating blockchain data. There are known and unknown deviations from the Bitcoin Core reference implementation. For consensus-critical code, use Bitcoin Core or a consensus-compliant implementation.
Crate stack
The project is split into multiple crates. Main ones:
- bitcoin: Top-level crate; re-exports primitives, units, and adds address, PSBT, BIP-32, taproot, signing.
- primitives: Block, transaction, script, witness types (re-exported by
bitcoin). - units: Amount, Weight, FeeRate, Sequence, locktime, etc.
- hashes: Hash types and traits used by primitives.
- secp256k1, bech32, hex-conservative, miniscript: External repos (rust-bitcoin org or community).
For JSON-RPC with Bitcoin Core use rust-bitcoincore-rpc.
Cargo features (bitcoin crate)
std(default),base64,bitcoinconsensus(script/tx validation),rand,serde,secp-lowmemory,secp-recovery.
<!-- Source references:
- sources/bitcoin-rust/README.md
- sources/bitcoin-rust/docs/crates.md
- sources/bitcoin-rust/bitcoin/src/lib.rs
-->
Core Types and Crate Stack
Main types (from bitcoin / primitives)
- Block / BlockHeader:
primitives::block;BlockHash,WitnessCommitment, merkle roots. - Transaction:
primitives::transaction;Txid,Wtxid,Ntxid;TxIn,TxOut,OutPoint;Version,Witness. - Script:
ScriptBuf/Script(borrowed);ScriptPubKey,ScriptSig,RedeemScript,WitnessScript,TapScript;Witnessfor witness stack. - Amounts:
Amount,SignedAmount(fromunits); useAmount::from_sat,to_sat, denomination helpers. - Locktime:
absolute::LockTime,relative::LockTime; sequence viaSequence. - Hashes:
Txid,Wtxid,BlockHash,ScriptHash,WScriptHash,PubkeyHash,WPubkeyHash(from hashes/crypto). - Network:
Network,NetworkKind,Params;Network::Bitcoin,Testnet,Signet,Regtest.
Re-export hierarchy: units → primitives → bitcoin; use types from the highest crate in scope (e.g. bitcoin::Transaction when using the bitcoin crate).
Crates in this repo
| Crate | Purpose |
|---|---|
| bitcoin | Main library; address, PSBT, BIP-32, taproot, consensus encoding |
| primitives | Block, tx, script, witness types |
| units | Amount, Weight, FeeRate, Sequence, time, etc. |
| hashes | Hash types and engines |
| consensus_encoding | Sans-I/O encoding (newer) |
| io | I/O traits for no_std |
| addresses | Address types (placeholder/split) |
| base58 | Base58 check encoding |
| crypto | Key and sighash crypto |
| p2p | P2P message types |
| bip158 | Compact block filters |
| internals | Internal shared code |
External: secp256k1, bech32, hex-conservative, miniscript (separate repos).
Versioning
- LTS: v0.30, v0.31 (security/bugfix); v0.32 actively maintained; v0.33 in development (primitives/units 1.0).
- Match dependency versions to the
bitcoinversion (seedocs/supported-versions.md).
<!-- Source references:
- sources/bitcoin-rust/bitcoin/src/lib.rs
- sources/bitcoin-rust/docs/crates.md
- sources/bitcoin-rust/docs/supported-versions.md
-->
BIP-32 Hierarchical Deterministic Keys
The bip32 module implements BIP-0032: extended private key (Xpriv), extended public key (Xpub), derivation paths, and child derivation. Use for HD wallets and PSBT key paths.
Types
- Xpriv:
network,depth,parent_fingerprint,child_number,private_key(secp256k1SecretKey),chain_code. - Xpub: Same structure but public key and chain code; no private key.
- ChildNumber: Normal or hardened; use for path segments.
- DerivationPath: Path of
ChildNumbers (e.g.m/84'/0'/0'). - KeySource: (fingerprint, path) used in PSBT global and per-input/output.
Derivation
use bitcoin::bip32::{Xpriv, Xpub, DerivationPath, ChildNumber};
// Parse or build path
let path = "m/84'/0'/0'/0/0".parse::<DerivationPath>()?;
// Derive from xpriv
let child = xpriv.derive_priv(&secp, &path)?;
let private_key = child.to_priv();
// Derive from xpub (non-hardened steps only)
let child_pub = xpub.derive_pub(&secp, &path)?;- Hardened derivation (
ChildNumber::Hardened) requiresXpriv; normal steps can useXpub. - Use
networkonXprivfor WIF when exporting; match network when importing.
Fingerprint and identifiers
- Fingerprint: First 4 bytes of parent key hash (for key source in PSBT).
- XKeyIdentifier: BIP-32 extended key identifier (hash160 of serialized pubkey); used in PSBT xpub map.
PSBT integration
- Global
xpub: mapXpub→KeySource(fingerprint + derivation path). - Per-input/per-output key paths: same
KeySourceformat so signers can derive keys and sign. - Use
bip32::KeySourcewhen building or reading PSBT key path data.
Key points
- BIP-0380 (new key derivation) is planned; current API is BIP-0032.
- Always use the correct network (mainnet vs testnet) for WIF and address creation from derived keys.
- Prefer deriving at the path you need rather than storing many keys.
<!-- Source references:
- sources/bitcoin-rust/bitcoin/src/bip32.rs
- sources/bitcoin-rust/docs/bip-32.md
- BIP-0032
-->
Keys and Signing
Keys and signing live in bitcoin::crypto::key, bitcoin::crypto::ecdsa, bitcoin::crypto::sighash, and re-exports at bitcoin::key and related modules.
Key types
- PrivateKey: WIF encode/decode;
NetworkKindfor WIF prefix; can produceKeypairandPublicKey. - PublicKey: Compressed (33 bytes) or uncompressed; use
CompressedPublicKeywhere required (e.g. P2WPKH). - XOnlyPublicKey: 32-byte x-only (Taproot); from
PublicKeyor secp256k1Keypair. - TweakedPublicKey / TweakedKeypair: Taproot output key and keypair after tweak.
use bitcoin::secp256k1::Secp256k1;
use bitcoin::{PrivateKey, PublicKey, CompressedPublicKey, Keypair, Network};
let secp = Secp256k1::new();
let (sk, pk) = secp256k1::generate_keypair(&mut rand::thread_rng());
let public_key = PublicKey::new(pk);
let compressed = CompressedPublicKey::from(public_key);
// WIF
let priv_key = PrivateKey::new(sk, Network::Bitcoin);
let wif = priv_key.to_wif();
let decoded = PrivateKey::from_wif(&wif)?;Sighash and signing
- EcdsaSighashType: Legacy (e.g.
All,Single,None) and optionalAnyoneCanPay. - TapSighashType: Default or custom (
TapSighashType::Alletc.); use withSighashCachefor Taproot. - SighashCache: Builds legacy, Segwit v0, or Taproot sighash for a transaction; then sign with secp256k1.
use bitcoin::sighash::{EcdsaSighashType, SighashCache, Prevouts};
use bitcoin::{Transaction, ScriptBuf};
let mut cache = SighashCache::new(&tx);
// Legacy
let sighash = cache.legacy_sighash(input_index, &script_code, amount.as_sat(), EcdsaSighashType::All)?;
// Segwit v0
let sighash = cache.segwit_sighash(input_index, &script_code, amount.as_sat(), EcdsaSighashType::All)?;
// Taproot (BIP-0341)
let prevouts = Prevouts::All(&outputs);
let sighash = cache.taproot_key_spend_sighash(prevouts, TapSighashType::Default)?;
// or taproot_script_spend_sighash with (leaf_hash, leaf_script)Sign the sighash (as secp256k1::Message) with the appropriate key; then attach the signature to the script_sig or witness.
BIP-32
Use bitcoin::bip32::Xpriv / Xpub for HD keys; derive children and get PrivateKey/PublicKey for signing. See features-bip32.
<!-- Source references:
- sources/bitcoin-rust/bitcoin/src/crypto/key.rs
- sources/bitcoin-rust/bitcoin/src/crypto/sighash.rs
- sources/bitcoin-rust/bitcoin/src/sighash.rs
- sources/bitcoin-rust/bitcoin/src/lib.rs
-->
Partially Signed Bitcoin Transactions (PSBT)
The psbt module implements BIP-0174 Partially Signed Bitcoin Transaction format (v0). Use for building, signing, and combining partially signed transactions. Input Finalizer role (script/witness construction from satisfaction) is not implemented here—use rust-miniscript for that.
Structure
use bitcoin::psbt::Psbt;
pub struct Psbt {
pub unsigned_tx: Transaction, // script_sigs and witnesses must be empty
pub version: u32,
pub xpub: BTreeMap<Xpub, KeySource>,
pub proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>>,
pub unknown: BTreeMap<raw::Key, Vec<u8>>,
pub inputs: Vec<Input>,
pub outputs: Vec<Output>,
}Creating a PSBT
let tx = Transaction { version: 2, lock_time: LockTime::ZERO, input: vec![...], output: vec![...] };
// Ensure tx has no script_sigs or witnesses
let psbt = Psbt::from_unsigned_tx(tx)?;Input/Output maps
- Input:
witness_utxo,non_witness_utxo,final_script_sig,final_script_witness, key paths, signatures, etc. - Output:
redeem_script,witness_script, key paths, BIP-32 derivation. - Add UTXO data (witness or full previous tx) and key derivation so signers can produce signatures.
Signing and extraction
- Sign inputs using sighash (legacy/Segwit/Taproot) and attach signatures to the corresponding PSBT input entries.
- Extract transaction:
psbt.extract_tx()orextract_tx_fee_rate_limit()to get aTransactiononce inputs are finalized. Extraction checks fee rate; useDEFAULT_MAX_FEE_RATEor a custom limit to avoid accidental overpayment.
Serialization
- PSBTs use base64 or raw bytes; use the
psbtmodule’s encode/decode helpers (andbase64feature if needed). - Non-standard sighash types in a PSBT are considered invalid by this library.
Key points
- Do not use for consensus; library is for construction and signing tooling.
- For finalizing inputs (computing script_sig/witness from a satisfaction), use rust-miniscript’s PSBT support.
- Always validate fee and outputs when extracting.
<!-- Source references:
- sources/bitcoin-rust/bitcoin/src/psbt/mod.rs
- sources/bitcoin-rust/README.md
- BIP-0174
-->
Script
Script types live in bitcoin::script and bitcoin::blockdata::script; primitives in primitives::script. Use ScriptBuf for owned scripts and Script for borrowed; ScriptPubKey, ScriptSig, RedeemScript, WitnessScript, TapScript for specific roles.
Builder
use bitcoin::script::Builder;
use bitcoin::opcodes::all::*;
use bitcoin::script::PushBytesBuf;
let script = Builder::new()
.push_int(0)
.push_slice(pubkey.serialize())
.push_opcode(OP_CHECKSIG)
.into_script();push_int(n),push_int_unchecked(n)for numbers.push_slice(bytes),push_key(pubkey)for keys.push_opcode(OP_*)for opcodes; useopcodes::all::*or specificOpcodevalues.into_script()yieldsScriptBuf.
Parsing and inspection
- Iterate instructions: use script’s iteration API (e.g.
instructions()where available) to get opcodes and push data. - Script hash:
ScriptHash,WScriptHashfor P2SH/P2WSH from script contents. - Extension traits:
ScriptExt,ScriptPubKeyExt,ScriptBufExt,TapScriptExt, etc. (re-exported underbitcoin::ext) for script-type checks and helpers.
Script pubkey and address
- Construct
ScriptPubKeyfrom address:address.script_pubkey(). - P2PKH, P2SH, P2WPKH, P2WSH, P2TR: use
Addressconstructors thenscript_pubkey()when you need the script form.
Locktime and sequence
absolute::LockTime,relative::LockTimefor nLockTime and nSequence semantics.Sequence(fromunits) for encode/decode and disable flags (RBF, locktime).
Key points
- Use
Builderfor constructing scripts; avoid hand-encoding unless necessary. - For script verification in a consensus-like context, the library is not suitable; use
bitcoinconsensusfeature only for non-consensus checks or tooling. - Taproot scripts use
TapScriptand taproot-specific extension methods.
<!-- Source references:
- sources/bitcoin-rust/bitcoin/src/blockdata/script/builder.rs
- sources/bitcoin-rust/bitcoin/src/blockdata/script/mod.rs
- sources/bitcoin-rust/bitcoin/src/lib.rs (ext re-exports)
-->
Taproot
Taproot support is in the taproot module and in crypto::key (tweaked keys, TapTweak trait). Use for P2TR outputs, key-path and script-path spends, and sighash.
Types
- TapLeafHash, TapNodeHash, TapTweakHash: Hashes used in taproot tree and tweak.
- TapLeafTag, TapBranchTag: Tags for leaf and branch hashes (BIP-0341).
- TapTweak (trait): Tweaking untweaked keys to get output key; implemented for
UntweakedPublicKeyandUntweakedKeypair. - TapSighash, TapSighashType: Sighash for Taproot; use with
SighashCache::taproot_*_sighash.
Key tweaking
use bitcoin::taproot::{TapTweak, TapTweakTag};
use bitcoin::key::UntweakedPublicKey;
// Output key from internal key (key-path spend)
let (output_key, _parity) = internal_key.tap_tweak(&secp, None);
// With script tree (script-path spend)
let (output_key, _parity) = internal_key.tap_tweak(&secp, Some(merkle_root));Use Address::p2tr with optional script tree to build the tweaked address; or Address::p2tr_tweaked if you already have the tweaked key.
Sighash
- Key-path:
SighashCache::taproot_key_spend_sighash(prevouts, TapSighashType::Default)(or custom type). - Script-path:
taproot_script_spend_sighash(prevouts, leaf_hash, leaf_script, ...)with the leaf being spent. - Sign the resulting
TapSighashwith the appropriate key (tweaked for key-path, or script key for script-path).
Script and tree
- TapScript: Script in a taproot leaf; use script builder and
TapScriptBuf/extension methods where provided. - Merkle tree construction: use
taproothelpers for leaf hashes and branch hashes (BIP-0341); pass merkle root intotap_tweakwhen building script-path outputs. - PSBT: Taproot keys and scripts appear in PSBT input maps; attach signatures and final script witness per BIP-0371.
Key points
- Taproot is entangled with
secp256k1across the codebase; key and taproot modules depend on it. - For script-path spends, leaf version and leaf script must match the committed tree.
- BIP-0341 defines the exact tweak and sighash formats; the library follows them.
<!-- Source references:
- sources/bitcoin-rust/bitcoin/src/taproot/mod.rs
- sources/bitcoin-rust/docs/taproot.md
- BIP-0341
-->