Skip to content

Commit 2543626

Browse files
authored
Merge pull request #114 from alexanderwiederin/docs-script
Feat(core): Improve Documentation for Script module
2 parents 6b3d7de + 271f8ec commit 2543626

File tree

1 file changed

+136
-3
lines changed

1 file changed

+136
-3
lines changed

src/core/script.rs

Lines changed: 136 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,53 @@
1+
//! Script pubkey types and operations.
2+
//!
3+
//! This module provides types for working with script pubkeys (also known as
4+
//! "locking scripts"), which define the conditions that must be met to spend a
5+
//! [`TxOut`].
6+
//!
7+
//! # Types
8+
//!
9+
//! The module provides two types:
10+
//!
11+
//! - [`ScriptPubkey`]: An owned script pubkey that manages its own memory
12+
//! - [`ScriptPubkeyRef`]: A borrowed reference to a script pubkey with a specific lifetime
13+
//!
14+
//! Both types implement the [`ScriptPubkeyExt`] trait, providing a unified interface
15+
//! for all script pubkey operations regardless of ownership.
16+
//!
17+
//! # Examples
18+
//!
19+
//! ## Creating and working with script pubkeys
20+
//!
21+
//! ```no_run
22+
//! # use bitcoinkernel::{prelude::*, ScriptPubkey};
23+
//! // Create a simple script from raw bytes
24+
//! let script = ScriptPubkey::new(&[0x76, 0xa9, 0x14]).unwrap();
25+
//!
26+
//! // Serialize back to bytes
27+
//! let bytes = script.to_bytes();
28+
//! assert_eq!(bytes, vec![0x76, 0xa9, 0x14]);
29+
//!
30+
//! // Use TryFrom for conversion
31+
//! let script2 = ScriptPubkey::try_from(bytes.as_slice()).unwrap();
32+
//! ```
33+
//!
34+
//! ## Creating standard script types
35+
//!
36+
//! ```no_run
37+
//! # use bitcoinkernel::ScriptPubkey;
38+
//! // P2PKH: OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
39+
//! let p2pkh_hex = "76a914deadbeefdeadbeefdeadbeefdeadbeefdeadbeef88ac";
40+
//! let p2pkh = ScriptPubkey::new(&hex::decode(p2pkh_hex).unwrap()).unwrap();
41+
//!
42+
//! // P2SH: OP_HASH160 <scriptHash> OP_EQUAL
43+
//! let p2sh_hex = "a914deadbeefdeadbeefdeadbeefdeadbeefdeadbeef87";
44+
//! let p2sh = ScriptPubkey::new(&hex::decode(p2sh_hex).unwrap()).unwrap();
45+
//!
46+
//! // P2WPKH: OP_0 <20-byte-pubkey-hash>
47+
//! let p2wpkh_hex = "0014deadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
48+
//! let p2wpkh = ScriptPubkey::new(&hex::decode(p2wpkh_hex).unwrap()).unwrap();
49+
//! ```
50+
151
use std::{ffi::c_void, marker::PhantomData};
252

353
use libbitcoinkernel_sys::{
@@ -12,8 +62,22 @@ use crate::{
1262
};
1363

1464
/// Common operations for script pubkeys, implemented by both owned and borrowed types.
65+
///
66+
/// This trait provides shared functionality for [`ScriptPubkey`] and [`ScriptPubkeyRef`],
67+
/// allowing code to work with either owned or borrowed script pubkeys.
1568
pub trait ScriptPubkeyExt: AsPtr<btck_ScriptPubkey> {
1669
/// Serializes the script to raw bytes.
70+
///
71+
/// Returns the script's raw byte representation.
72+
///
73+
/// # Examples
74+
///
75+
/// ```no_run
76+
/// # use bitcoinkernel::{prelude::*, ScriptPubkey};
77+
/// let script = ScriptPubkey::new(&[0x76, 0xa9]).unwrap();
78+
/// let bytes = script.to_bytes();
79+
/// assert_eq!(bytes, vec![0x76, 0xa9]);
80+
/// ```
1781
fn to_bytes(&self) -> Vec<u8> {
1882
c_serialize(|callback, user_data| unsafe {
1983
btck_script_pubkey_to_bytes(self.as_ptr(), Some(callback), user_data)
@@ -22,10 +86,25 @@ pub trait ScriptPubkeyExt: AsPtr<btck_ScriptPubkey> {
2286
}
2387
}
2488

25-
/// A single script pubkey containing spending conditions for a transaction output.
89+
/// A single script pubkey containing spending conditions for a [`TxOut`].
90+
///
91+
/// Script pubkeys define the conditions that must be met to spend a transaction output.
92+
/// They are also called "locking scripts" because they lock the output to specific
93+
/// spending conditions.
94+
///
95+
/// Script pubkeys can be created from raw script bytes or retrieved from an existing
96+
/// [`TxOut`].
97+
///
98+
/// # Examples
2699
///
27-
/// Script pubkeys can be created from raw script bytes or retrieved from existing
28-
/// transaction outputs.
100+
/// Creating a simple script:
101+
///
102+
/// ```no_run
103+
/// # use bitcoinkernel::{prelude::*, ScriptPubkey};
104+
/// let script_bytes = vec![0x76, 0xa9, 0x14]; // OP_DUP OP_HASH160 OP_PUSHBYTES_20
105+
/// let script = ScriptPubkey::new(&script_bytes).unwrap();
106+
/// assert_eq!(script.to_bytes(), script_bytes);
107+
/// ```
29108
#[derive(Debug)]
30109
pub struct ScriptPubkey {
31110
inner: *mut btck_ScriptPubkey,
@@ -35,6 +114,28 @@ unsafe impl Send for ScriptPubkey {}
35114
unsafe impl Sync for ScriptPubkey {}
36115

37116
impl ScriptPubkey {
117+
/// Creates a new script pubkey from raw script bytes.
118+
///
119+
/// # Arguments
120+
///
121+
/// * `script_bytes` - The raw bytes representing the script
122+
///
123+
/// # Returns
124+
///
125+
/// * `Ok(ScriptPubkey)` - Successfully created script pubkey
126+
/// * `Err(KernelError::Internal)` - If the script could not be created
127+
///
128+
/// # Examples
129+
///
130+
/// ```no_run
131+
/// # use bitcoinkernel::ScriptPubkey;
132+
/// // Create a P2PKH script
133+
/// let p2pkh = ScriptPubkey::new(&[
134+
/// 0x76, 0xa9, 0x14, // OP_DUP OP_HASH160 OP_PUSHBYTES_20
135+
/// // ... pubkey hash bytes ...
136+
/// 0x88, 0xac // OP_EQUALVERIFY OP_CHECKSIG
137+
/// ]).unwrap();
138+
/// ```
38139
pub fn new(script_bytes: &[u8]) -> Result<Self, KernelError> {
39140
let inner = unsafe {
40141
btck_script_pubkey_create(script_bytes.as_ptr() as *const c_void, script_bytes.len())
@@ -49,6 +150,13 @@ impl ScriptPubkey {
49150
}
50151
}
51152

153+
/// Creates a borrowed reference to this script pubkey.
154+
///
155+
/// This allows converting from an owned [`ScriptPubkey`] to a [`ScriptPubkeyRef`]
156+
/// without copying the underlying data.
157+
///
158+
/// # Lifetime
159+
/// The returned reference is valid for the lifetime of this [`ScriptPubkey`].
52160
pub fn as_ref(&self) -> ScriptPubkeyRef<'_> {
53161
unsafe { ScriptPubkeyRef::from_ptr(self.inner as *const _) }
54162
}
@@ -102,6 +210,16 @@ impl From<&ScriptPubkey> for Vec<u8> {
102210
}
103211
}
104212

213+
/// A borrowed reference to a script pubkey.
214+
///
215+
/// Provides zero-copy access to script pubkey data. It implements [`Copy`],
216+
/// making it cheap to pass around.
217+
///
218+
/// # Lifetime
219+
/// The reference is only valid as long as the data it references remains alive.
220+
///
221+
/// # Thread Safety
222+
/// `ScriptPubkeyRef` is both [`Send`] and [`Sync`].
105223
pub struct ScriptPubkeyRef<'a> {
106224
inner: *const btck_ScriptPubkey,
107225
marker: PhantomData<&'a ()>,
@@ -111,6 +229,21 @@ unsafe impl<'a> Send for ScriptPubkeyRef<'a> {}
111229
unsafe impl<'a> Sync for ScriptPubkeyRef<'a> {}
112230

113231
impl<'a> ScriptPubkeyRef<'a> {
232+
/// Creates an owned copy of this script pubkey.
233+
///
234+
/// This allocates a new [`ScriptPubkey`] with its own copy of the script data.
235+
///
236+
/// # Examples
237+
///
238+
/// ```no_run
239+
/// # use bitcoinkernel::{prelude::*, ScriptPubkey};
240+
/// let owned_script = {
241+
/// let script = ScriptPubkey::new(&[0x76, 0xa9]).unwrap();
242+
/// let script_ref = script.as_ref();
243+
/// script_ref.to_owned() // Survives after script is dropped
244+
/// };
245+
/// assert_eq!(owned_script.to_bytes(), vec![0x76, 0xa9]);
246+
/// ```
114247
pub fn to_owned(&self) -> ScriptPubkey {
115248
ScriptPubkey {
116249
inner: unsafe { btck_script_pubkey_copy(self.inner) },

0 commit comments

Comments
 (0)