bitcoin_scripts/lib.rs
1// BP foundation libraries Bitcoin crates implementing the foundations of
2// Bitcoin protocol by LNP/BP Association (https://lnp-bp.org)
3//
4// Written in 2020-2022 by
5// Dr. Maxim Orlovsky <orlovsky@lnp-bp.org>
6//
7// This software is distributed without any warranty.
8//
9// You should have received a copy of the Apache-2.0 License
10// along with this software.
11// If not, see <https://opensource.org/licenses/Apache-2.0>.
12
13// Coding conventions
14#![recursion_limit = "256"]
15#![deny(dead_code, missing_docs, warnings)]
16
17//! # Bitcoin script types
18//!
19//! Bitcoin doesn't make a distinction between Bitcoin script coming from
20//! different sources, like *scriptPubKey* in transaction output or *witness*
21//! and *scriptSig* in transaction input. There are many other possible script
22//! containers for Bitcoin script: redeem script, witness script, taproot leaf
23//! bitcoin_scripts of different versions. In fact, any "script" of
24//! [`bitcoin::Script`] type can be used for inputs and outputs. What is a valid
25//! script for in one context will not be a valid script for some other. That
26//! would mean that in principle with existing [`bitcoin::Script`] type every
27//! input script can be used as an output script, leading to potentially harmful
28//! code coming from an unaware developer.
29//!
30//! While all [`bitcoin::Script`]s have the same parsing rules converting byte
31//! string into a set of instructions (i.e. the same **syntax**), there are
32//! multiple ways how the consensus meaning of these instructions will be
33//! interpreted under different contexts (different **semantics**). Moreover,
34//! the bitcoin_scripts may be nested - or to be committed into some other
35//! Bitcoin script – in a nested structures like in several layers, like
36//! *redeemScript* inside of *scriptSig* used for P2SH, or *tapScript* within
37//! *witnessScript* coming from *witness* field for Taproot. These nested layers
38//! do distinguish on the information they contain, since some of them only
39//! commit to the hashes of the nested bitcoin_scripts ([`bitcoin::ScriptHash`],
40//! [`WitnessProgram`]) or public keys ([`bitcoin::PubkeyHash`],
41//! [`bitcoin::WPubkeyHash`]), while other contain the full source of the
42//! script.
43//!
44//! The present type system represents a solution to the problem: it distinguish
45//! different logical types by introducing `Script` wrapper types. It defines
46//! [`LockScript`] as bottom layer of a script, containing no other script
47//! commitments (in form of their hashes). It also defines types above on it:
48//! [`PubkeyScript`] (for whatever is there in `scriptPubkey` field
49//! of a [`bitcoin::TxOut`]), [`SigScript`] (for whatever comes from `scriptSig`
50//! field of [`bitcoin::TxIn`]), [`RedeemScript`] and [`WitnessScript`].
51//! For taproot, we define [`LeafScript`] as a top level of specific script
52//! branch (see [`bitcoin::util::psbt::TapTree`]) and [`crate::TapScript`] as a
53//! type specific for the current `0xC0` tapleaf version semantics, defined in
54//! BIP-342.
55//!
56//! There are conversion functions, which, for instance, can analyse
57//! [`PubkeyScript`] and if it is a custom script or P2PK return a
58//! [`LockScript`] type - or otherwise fail with error. These conversions
59//! functions reside in [`convert`] module. So with this type system one is
60//! always sure which semantic information it does contain.
61//!
62//! ## Type conversion
63//!
64//! ```text
65//! LockScript -+-> (PubkeyScript + RedeemScript) -+-> SigScript
66//! | +-> WitnessScript
67//! +-> PubkeyScript
68//! |
69//! TapScript ----> LeafScript
70//!
71//! PubkeyScript --?--> LockScript
72//! ```
73
74#[macro_use]
75extern crate amplify;
76#[macro_use]
77extern crate strict_encoding;
78#[cfg(feature = "serde")]
79#[macro_use]
80extern crate serde_crate as serde;
81
82pub mod address;
83pub mod convert;
84pub mod hlc;
85pub mod taproot;
86mod types;
87
88pub use convert::ConvertInfo;
89#[cfg(feature = "miniscript")]
90pub use parser::PubkeyParseError;
91pub use types::{
92 IntoNodeHash, LeafScript, LockScript, PubkeyScript, RedeemScript, ScriptCode, ScriptSet,
93 SigScript, TapNodeHash, TapScript, TaprootWitness, TaprootWitnessError, WitnessProgram,
94 WitnessScript,
95};