Move script_hash and wscript_hash to primitives
What changed, and why it matters
This commit is a routine internal code reorganization. It moves two helper methods, `script_hash` and `wscript_hash`, from one Rust module to another within the same project. The methods still do exactly the same thing—compute the same Bitcoin script hashes—and are still called the same way. There is no change to security behavior, no bug fix, and no vulnerability.
No security action needed. Treat as normal maintenance/refactoring.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch relocates script_hash and wscript_hash from extension traits in bitcoin::blockdata::script to inherent impl blocks in primitives::script. The implementations remain identical wrappers around ScriptHash::from_script and WScriptHash::from_script. Call sites are updated only to remove now-unnecessary trait imports (WitnessScriptExt). This is pure refactoring with no functional or cryptographic change.
Changed components
bitcoin/src/blockdata/script/borrowed.rsbitcoin/src/blockdata/script/owned.rsbitcoin/src/address/mod.rsprimitives/src/script/borrowed.rsInspect captured patch +31 / −21
diff --git a/bitcoin/src/address/mod.rs b/bitcoin/src/address/mod.rs
index 4964f06b..c99050d7 100644
--- a/bitcoin/src/address/mod.rs
+++ b/bitcoin/src/address/mod.rs
@@ -66,7 +66,7 @@ use crate::script::witness_version::WitnessVersion;
use crate::script::{
self, BuilderExt as _, RedeemScriptSizeError, Script, ScriptExt as _, ScriptHash,
ScriptHashableTag, ScriptPubKey, ScriptPubKeyBuf, ScriptPubKeyBufExt as _, WScriptHash,
- WitnessScript, WitnessScriptExt as _, WitnessScriptSizeError,
+ WitnessScript, WitnessScriptSizeError,
};
use crate::taproot::TapNodeHash;
diff --git a/bitcoin/src/blockdata/script/borrowed.rs b/bitcoin/src/blockdata/script/borrowed.rs
index f3ee64c3..71516d14 100644
--- a/bitcoin/src/blockdata/script/borrowed.rs
+++ b/bitcoin/src/blockdata/script/borrowed.rs
@@ -7,8 +7,8 @@ use internals::array::ArrayExt; // For `split_first`.
use super::witness_version::WitnessVersion;
use super::{
Builder, Instruction, InstructionIndices, Instructions, PushBytes, RedeemScript,
- RedeemScriptSizeError, Script, ScriptHash, ScriptHashableTag, ScriptPubKey, ScriptSig,
- TapScript, WScriptHash, WitnessScript, WitnessScriptSizeError,
+ RedeemScriptSizeError, Script, ScriptHashableTag, ScriptPubKey, ScriptSig, TapScript,
+ WitnessScript, WitnessScriptSizeError,
};
use crate::encoding::{Encode, ExactSizeEncoder};
use crate::key::{LegacyPublicKey, UntweakedPublicKey, WPubkeyHash};
@@ -143,14 +143,6 @@ internal_macros::define_extension_trait! {
// These methods only exist for scriptPubKey and redeemScript, as indicated by the
// where clauses on them.
- /// Returns 160-bit hash of the script for P2SH outputs.
- #[inline]
- fn script_hash(&self) -> Result<ScriptHash, RedeemScriptSizeError>
- where T: ScriptHashableTag
- {
- ScriptHash::from_script(self)
- }
-
/// Computes the P2SH output corresponding to this redeem script.
fn to_p2sh(&self) -> Result<ScriptPubKeyBuf, RedeemScriptSizeError>
where T: ScriptHashableTag
@@ -184,12 +176,6 @@ internal_macros::define_extension_trait! {
internal_macros::define_extension_trait! {
/// Extension functionality for the [`WitnessScript`] type.
pub trait WitnessScriptExt impl for WitnessScript {
- /// Returns 256-bit hash of the script for P2WSH outputs.
- #[inline]
- fn wscript_hash(&self) -> Result<WScriptHash, WitnessScriptSizeError> {
- WScriptHash::from_script(self)
- }
-
/// Computes the P2WSH output corresponding to this witnessScript (aka the "witness redeem
/// script").
fn to_p2wsh(&self) -> Result<ScriptPubKeyBuf, WitnessScriptSizeError> {
diff --git a/bitcoin/src/blockdata/script/owned.rs b/bitcoin/src/blockdata/script/owned.rs
index 33c061a5..5706fe57 100644
--- a/bitcoin/src/blockdata/script/owned.rs
+++ b/bitcoin/src/blockdata/script/owned.rs
@@ -145,8 +145,6 @@ crate::internal_macros::define_extension_trait! {
///
/// [`WitnessExt::p2wsh`]: crate::blockdata::witness::WitnessExt::p2wsh
fn p2sh_p2wsh(witness_script: &WitnessScript) -> Result<ScriptSigBuf, super::WitnessScriptSizeError> {
- use super::WitnessScriptExt as _;
-
let hash = witness_script.wscript_hash()?;
let redeem_script: super::ScriptPubKeyBuf = Builder::new().push_int_unchecked(0).push_slice(hash).into_script();
Ok(Builder::new().push_slice(<&PushBytes>::try_from(redeem_script.as_bytes()).expect("redeem script is 34 bytes")).into_script())
diff --git a/primitives/src/script/borrowed.rs b/primitives/src/script/borrowed.rs
index fcd2f33f..9bb94fc2 100644
--- a/primitives/src/script/borrowed.rs
+++ b/primitives/src/script/borrowed.rs
@@ -16,9 +16,11 @@ use super::{ScriptBuf, P2A_PROGRAM};
use crate::opcodes::all::{OP_CHECKSIG, OP_DUP, OP_EQUAL, OP_EQUALVERIFY, OP_HASH160, OP_RETURN};
use crate::opcodes::{Opcode, OP_PUSHBYTES_2, OP_PUSHBYTES_20, OP_PUSHBYTES_32};
use crate::prelude::{Box, ToOwned, Vec};
-use crate::script::ScriptHashableTag;
+use crate::script::{
+ RedeemScriptSizeError, ScriptHash, ScriptHashableTag, WScriptHash, WitnessScriptSizeError,
+};
use crate::witness_version::WitnessVersion;
-use crate::ScriptPubKey;
+use crate::{ScriptPubKey, WitnessScript};
// Defined in `REPO_DIR/include/newtype.rs`.
crate::transparent_newtype! {
@@ -289,6 +291,30 @@ impl ScriptPubKey {
}
}
+impl WitnessScript {
+ /// Returns 256-bit hash of the script for P2WSH outputs.
+ ///
+ /// # Errors
+ ///
+ /// Returns an error if the script exceeds 10,000 bytes.
+ #[inline]
+ pub fn wscript_hash(&self) -> Result<WScriptHash, WitnessScriptSizeError> {
+ WScriptHash::from_script(self)
+ }
+}
+
+impl<T: ScriptHashableTag> Script<T> {
+ /// Returns 160-bit hash of the script for P2SH outputs.
+ ///
+ /// # Errors
+ ///
+ /// Returns an error if the script exceeds 520 bytes.
+ #[inline]
+ pub fn script_hash(&self) -> Result<ScriptHash, RedeemScriptSizeError> {
+ ScriptHash::from_script(self)
+ }
+}
+
impl<T> Encode for Script<T> {
type Encoder<'e>
= ScriptEncoder<'e>
Why this scored 15/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.