What changed, and why it matters
This commit is a routine internal code reorganization in the rust-bitcoin library. It moves a helper trait (ScriptPubKeyBufExt) and its functions from one internal module to another, and re-exports it so existing users see no change. There is no indication this fixes a security bug or introduces a vulnerability.
No security action required. Treat as normal maintenance/refactoring commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch relocates the ScriptPubKeyBufExt trait and its implementations (new_p2pk, new_p2pkh, new_p2tr, new_p2tr_tweaked, new_witness_program) from bitcoin/src/blockdata/script/owned.rs to addresses/src/lib.rs, then re-exports the trait in bitcoin to preserve the public API. The new_p2pk implementation is adjusted to use Builder::push_slice(pubkey.serialize()) instead of Builder::push_key(pubkey). This is a refactor to resolve a module-dependency issue (new_p2pkh needs a crypto hash type, preventing immediate movement to primitives). No security-relevant behavior change is visible in the diff.
Changed components
rust-bitcoin addresses craterust-bitcoin bitcoin crate script moduleInspect captured patch +92 / −55
diff --git a/addresses/src/lib.rs b/addresses/src/lib.rs
index 11e2a565..3319238a 100644
--- a/addresses/src/lib.rs
+++ b/addresses/src/lib.rs
@@ -26,9 +26,94 @@ extern crate std;
pub mod witness_program;
#[cfg(feature = "alloc")]
-use primitives::script::{Builder, PushBytes, ScriptBuf};
+use crypto::key::{LegacyPublicKey, UntweakedPublicKey, TweakedPublicKey, PubkeyHash};
+#[cfg(feature = "alloc")]
+use primitives::opcodes::all::{OP_CHECKSIG, OP_DUP, OP_EQUALVERIFY, OP_HASH160};
+#[cfg(feature = "alloc")]
+use primitives::script::{Builder, PushBytes, ScriptBuf, ScriptPubKeyBuf};
#[cfg(feature = "alloc")]
use primitives::witness_version::WitnessVersion;
+#[cfg(feature = "alloc")]
+use taproot_primitives::{TapNodeHash, TapTweak as _};
+
+#[cfg(feature = "alloc")]
+use witness_program::WitnessProgram;
+
+/// Extension functionality for the [`ScriptPubKeyBuf`] type.
+#[cfg(feature = "alloc")]
+pub trait ScriptPubKeyBufExt: sealed::Sealed {
+ /// Generates P2PK-type of scriptPubkey.
+ fn new_p2pk(pubkey: LegacyPublicKey) -> Self;
+
+ /// Generates P2PKH-type of scriptPubkey.
+ fn new_p2pkh(pubkey_hash: PubkeyHash) -> Self;
+
+ /// Generates P2TR for script spending path using an internal public key and some optional
+ /// script tree Merkle root.
+ fn new_p2tr<K: Into<UntweakedPublicKey>>(
+ internal_key: K,
+ merkle_root: Option<TapNodeHash>,
+ ) -> Self;
+
+ /// Generates P2TR for key spending path for a known [`TweakedPublicKey`].
+ fn new_p2tr_tweaked(output_key: TweakedPublicKey) -> Self;
+
+ /// Generates P2WSH-type of scriptPubkey with a given [`WitnessProgram`].
+ fn new_witness_program(witness_program: &WitnessProgram) -> Self;
+}
+
+#[cfg(feature = "alloc")]
+impl ScriptPubKeyBufExt for ScriptPubKeyBuf {
+ /// Generates P2PK-type of scriptPubkey.
+ fn new_p2pk(pubkey: LegacyPublicKey) -> Self {
+ Builder::new()
+ .push_slice(pubkey.serialize())
+ .push_opcode(OP_CHECKSIG)
+ .into_script()
+ }
+
+ fn new_p2pkh(pubkey_hash: PubkeyHash) -> Self {
+ Builder::new()
+ .push_opcode(OP_DUP)
+ .push_opcode(OP_HASH160)
+ .push_slice(pubkey_hash)
+ .push_opcode(OP_EQUALVERIFY)
+ .push_opcode(OP_CHECKSIG)
+ .into_script()
+ }
+
+ /// Generates P2TR for script spending path using an internal public key and some optional
+ /// script tree Merkle root.
+ fn new_p2tr<K: Into<UntweakedPublicKey>>(
+ internal_key: K,
+ merkle_root: Option<TapNodeHash>,
+ ) -> Self {
+ let internal_key = internal_key.into();
+ let output_key = internal_key.tap_tweak(merkle_root);
+ // output key is 32 bytes long, so it's safe to use `new_witness_program_unchecked` (Segwitv1)
+ new_witness_program_unchecked(WitnessVersion::V1, output_key.serialize())
+ }
+
+ /// Generates P2TR for key spending path for a known [`TweakedPublicKey`].
+ fn new_p2tr_tweaked(output_key: TweakedPublicKey) -> Self {
+ // output key is 32 bytes long, so it's safe to use `new_witness_program_unchecked` (Segwitv1)
+ new_witness_program_unchecked(WitnessVersion::V1, output_key.serialize())
+ }
+
+ /// Generates P2WSH-type of scriptPubkey with a given [`WitnessProgram`].
+ fn new_witness_program(witness_program: &WitnessProgram) -> Self {
+ Builder::new()
+ .push_opcode(witness_program.version().into())
+ .push_slice(witness_program.program())
+ .into_script()
+ }
+}
+
+#[cfg(feature = "alloc")]
+mod sealed {
+ pub trait Sealed {}
+ impl Sealed for super::ScriptPubKeyBuf {}
+}
/// Generates P2WSH-type of scriptPubkey with a given [`WitnessVersion`] and the program bytes.
/// Does not do any checks on version or program length.
diff --git a/bitcoin/src/blockdata/script/owned.rs b/bitcoin/src/blockdata/script/owned.rs
index a31c22a4..33c061a5 100644
--- a/bitcoin/src/blockdata/script/owned.rs
+++ b/bitcoin/src/blockdata/script/owned.rs
@@ -5,21 +5,20 @@ use core::ops::Deref;
use super::{
opcode_to_verify, write_scriptint, Builder, Error, Instruction, PushBytes, ScriptBuf,
- ScriptExtPriv as _, ScriptPubKeyBuf, ScriptSigBuf, WitnessScript,
-};
-use crate::key::{
- FullPublicKey, LegacyPublicKey, PubkeyHash, TapTweak, TweakedPublicKey, UntweakedPublicKey,
- WPubkeyHash,
+ ScriptExtPriv as _, ScriptSigBuf, WitnessScript,
};
+use crate::key::{FullPublicKey, WPubkeyHash};
use crate::opcodes::all::*;
use crate::opcodes::{self, Opcode};
use crate::prelude::Vec;
-use crate::script::witness_program::WitnessProgram;
use crate::script::witness_version::WitnessVersion;
use crate::script::{self, BuilderExt as _};
-use crate::taproot::TapNodeHash;
use crate::{internal_macros, ToU64 as _};
+#[rustfmt::skip] // Keep public re-exports separate.
+#[doc(inline)]
+pub use addresses::ScriptPubKeyBufExt;
+
internal_macros::define_extension_trait! {
/// Extension functionality for the [`ScriptBuf`] type.
pub trait ScriptBufExt<T> impl<T> for ScriptBuf<T> {
@@ -123,53 +122,6 @@ internal_macros::define_extension_trait! {
}
}
-crate::internal_macros::define_extension_trait! {
- /// Extension functionality for the [`ScriptPubKeyBuf`] type.
- pub trait ScriptPubKeyBufExt impl for ScriptPubKeyBuf {
- /// Generates P2PK-type of scriptPubkey.
- fn new_p2pk(pubkey: LegacyPublicKey) -> Self {
- Builder::new().push_key(pubkey).push_opcode(OP_CHECKSIG).into_script()
- }
-
- /// Generates P2PKH-type of scriptPubkey.
- fn new_p2pkh(pubkey_hash: PubkeyHash) -> Self {
- Builder::new()
- .push_opcode(OP_DUP)
- .push_opcode(OP_HASH160)
- .push_slice(pubkey_hash)
- .push_opcode(OP_EQUALVERIFY)
- .push_opcode(OP_CHECKSIG)
- .into_script()
- }
-
- /// Generates P2TR for script spending path using an internal public key and some optional
- /// script tree Merkle root.
- fn new_p2tr<K: Into<UntweakedPublicKey>>(
- internal_key: K,
- merkle_root: Option<TapNodeHash>,
- ) -> Self {
- let internal_key = internal_key.into();
- let output_key = internal_key.tap_tweak(merkle_root);
- // output key is 32 bytes long, so it's safe to use `new_witness_program_unchecked` (Segwitv1)
- script::new_witness_program_unchecked(WitnessVersion::V1, output_key.serialize())
- }
-
- /// Generates P2TR for key spending path for a known [`TweakedPublicKey`].
- fn new_p2tr_tweaked(output_key: TweakedPublicKey) -> Self {
- // output key is 32 bytes long, so it's safe to use `new_witness_program_unchecked` (Segwitv1)
- script::new_witness_program_unchecked(WitnessVersion::V1, output_key.serialize())
- }
-
- /// Generates P2WSH-type of scriptPubkey with a given [`WitnessProgram`].
- fn new_witness_program(witness_program: &WitnessProgram) -> Self {
- Builder::new()
- .push_opcode(witness_program.version().into())
- .push_slice(witness_program.program())
- .into_script()
- }
- }
-}
-
crate::internal_macros::define_extension_trait! {
/// Extension functionality for the [`ScriptSigBuf`] type.
pub trait ScriptSigBufExt impl for ScriptSigBuf {
Why this scored 17/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.