Skip to content

Commit f6d247e

Browse files
committed
address: introduce constructors for (W)ScriptHash
This commit was originally just supposed to add constructors for WScriptHash and ScriptHash to allow them to be created from scripts without calling the generic `hash()` method (which will go away in 1.0). But in doing so, I noticed that the Address::p2shwpkh constructor is wrong. It computes the ScriptHash of a public key rather than a WPubkeyHash. Now, these two hashes are both just hash160s so there's no difference and no user-visible bug here. But jeez.
1 parent fe59e1a commit f6d247e

2 files changed

Lines changed: 23 additions & 8 deletions

File tree

src/address.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ impl Address {
253253
) -> Address {
254254
Address {
255255
params,
256-
payload: Payload::ScriptHash(ScriptHash::hash(&script[..])),
256+
payload: Payload::ScriptHash(ScriptHash::hash_script(script)),
257257
blinding_pubkey: blinder,
258258
}
259259
}
@@ -281,22 +281,23 @@ impl Address {
281281

282282
/// Create a pay to script address that embeds a witness pay to public key
283283
/// This is a segwit address type that looks familiar (as p2sh) to legacy clients
284+
///
285+
/// # Panics
286+
///
287+
/// Panics if the provided public key is not compressed.
284288
pub fn p2shwpkh(
285289
pk: &PublicKey,
286290
blinder: Option<secp256k1_zkp::PublicKey>,
287291
params: &'static AddressParams,
288292
) -> Address {
289-
let mut hash_engine = ScriptHash::engine();
290-
pk.write_into(&mut hash_engine)
291-
.expect("engines don't error");
292-
293+
let pkh = pk.wpubkey_hash().expect("public key must be uncompressed");
293294
let builder = script::Builder::new()
294295
.push_int(0)
295-
.push_slice(&ScriptHash::from_engine(hash_engine)[..]);
296+
.push_slice(pkh.as_ref());
296297

297298
Address {
298299
params,
299-
payload: Payload::ScriptHash(ScriptHash::hash(builder.into_script().as_bytes())),
300+
payload: Payload::ScriptHash(ScriptHash::hash_script(&builder.into_script())),
300301
blinding_pubkey: blinder,
301302
}
302303
}
@@ -311,7 +312,7 @@ impl Address {
311312
params,
312313
payload: Payload::WitnessProgram {
313314
version: Fe32::Q,
314-
program: WScriptHash::hash(&script[..])[..].to_vec(),
315+
program: WScriptHash::hash_script(script).as_byte_array().to_vec(),
315316
},
316317
blinding_pubkey: blinder,
317318
}

src/hash_types.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,20 @@ impl_hashencode!(Sighash);
7070
impl_hashencode!(BlockHash);
7171
impl_hashencode!(TxMerkleNode);
7272

73+
impl ScriptHash {
74+
/// Computes the `ScriptHash` of a script.
75+
pub fn hash_script(s: &crate::Script) -> Self {
76+
Self(hash160::Hash::hash(s.as_bytes()))
77+
}
78+
}
79+
80+
impl WScriptHash {
81+
/// Computes the `WScriptHash` of a script.
82+
pub fn hash_script(s: &crate::Script) -> Self {
83+
Self(sha256::Hash::hash(s.as_bytes()))
84+
}
85+
}
86+
7387
#[cfg(test)]
7488
#[cfg(feature = "serde")]
7589
mod serde_tests {

0 commit comments

Comments
 (0)