From 2197f1377fcacb11adfed03bc9100c29760b90cb Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Fri, 23 Jun 2023 13:11:48 +1000 Subject: [PATCH 1/2] Improve PubkeyHash and WPubkeyHash Improve the pubkey hash types by doing: - Define the types in the `crypto::key` module - Add From<&PublicKey> impl for `PubkeyHash` Keep the current crate level re-export so this does not impact the public API _if_ people are using the re-export but is still a breaking change. --- bitcoin/src/address.rs | 4 ++-- bitcoin/src/blockdata/script/owned.rs | 6 ++++-- bitcoin/src/blockdata/script/tests.rs | 3 +-- bitcoin/src/crypto/key.rs | 13 ++++++++++++- bitcoin/src/hash_types.rs | 8 ++------ bitcoin/src/lib.rs | 6 ++---- 6 files changed, 23 insertions(+), 17 deletions(-) diff --git a/bitcoin/src/address.rs b/bitcoin/src/address.rs index ced80341..e05fe9ea 100644 --- a/bitcoin/src/address.rs +++ b/bitcoin/src/address.rs @@ -44,8 +44,8 @@ use crate::blockdata::constants::{ use crate::blockdata::script::witness_program::{self, WitnessProgram}; use crate::blockdata::script::witness_version::{self, WitnessVersion}; use crate::blockdata::script::{self, Script, ScriptBuf}; -use crate::crypto::key::{PublicKey, TapTweak, TweakedPublicKey, UntweakedPublicKey}; -use crate::hash_types::{PubkeyHash, ScriptHash}; +use crate::crypto::key::{PubkeyHash, PublicKey, TapTweak, TweakedPublicKey, UntweakedPublicKey}; +use crate::hash_types::ScriptHash; use crate::network::Network; use crate::prelude::*; use crate::taproot::TapNodeHash; diff --git a/bitcoin/src/blockdata/script/owned.rs b/bitcoin/src/blockdata/script/owned.rs index 24f8f83f..d54b9048 100644 --- a/bitcoin/src/blockdata/script/owned.rs +++ b/bitcoin/src/blockdata/script/owned.rs @@ -10,8 +10,10 @@ use crate::blockdata::opcodes::{self}; use crate::blockdata::script::witness_program::WitnessProgram; use crate::blockdata::script::witness_version::WitnessVersion; use crate::blockdata::script::{opcode_to_verify, Builder, Instruction, PushBytes, Script}; -use crate::hash_types::{PubkeyHash, ScriptHash, WPubkeyHash, WScriptHash}; -use crate::key::{PublicKey, TapTweak, TweakedPublicKey, UntweakedPublicKey}; +use crate::hash_types::{ScriptHash, WScriptHash}; +use crate::key::{ + PubkeyHash, PublicKey, TapTweak, TweakedPublicKey, UntweakedPublicKey, WPubkeyHash, +}; use crate::prelude::*; use crate::taproot::TapNodeHash; diff --git a/bitcoin/src/blockdata/script/tests.rs b/bitcoin/src/blockdata/script/tests.rs index c1bf41d3..4b494a46 100644 --- a/bitcoin/src/blockdata/script/tests.rs +++ b/bitcoin/src/blockdata/script/tests.rs @@ -8,8 +8,7 @@ use hex_lit::hex; use super::*; use crate::blockdata::opcodes; use crate::consensus::encode::{deserialize, serialize}; -use crate::crypto::key::{PublicKey, XOnlyPublicKey}; -use crate::hash_types::{PubkeyHash, WPubkeyHash}; +use crate::crypto::key::{PubkeyHash, PublicKey, WPubkeyHash, XOnlyPublicKey}; #[test] #[rustfmt::skip] diff --git a/bitcoin/src/crypto/key.rs b/bitcoin/src/crypto/key.rs index fcfe14e7..5ac93873 100644 --- a/bitcoin/src/crypto/key.rs +++ b/bitcoin/src/crypto/key.rs @@ -17,7 +17,6 @@ pub use secp256k1::rand; pub use secp256k1::{self, constants, KeyPair, Parity, Secp256k1, Verification, XOnlyPublicKey}; use crate::crypto::ecdsa; -use crate::hash_types::{PubkeyHash, WPubkeyHash}; use crate::network::Network; use crate::prelude::*; use crate::taproot::{TapNodeHash, TapTweakHash}; @@ -299,10 +298,22 @@ impl FromStr for PublicKey { } } +hashes::hash_newtype! { + /// A hash of a public key. + pub struct PubkeyHash(hash160::Hash); + /// SegWit version of a public key hash. + pub struct WPubkeyHash(hash160::Hash); +} +crate::hash_types::impl_asref_push_bytes!(PubkeyHash, WPubkeyHash); + impl From for PubkeyHash { fn from(key: PublicKey) -> PubkeyHash { key.pubkey_hash() } } +impl From<&PublicKey> for PubkeyHash { + fn from(key: &PublicKey) -> PubkeyHash { key.pubkey_hash() } +} + /// A Bitcoin ECDSA private key #[derive(Copy, Clone, PartialEq, Eq)] #[cfg_attr(feature = "std", derive(Debug))] diff --git a/bitcoin/src/hash_types.rs b/bitcoin/src/hash_types.rs index b9b9f989..5b1c4636 100644 --- a/bitcoin/src/hash_types.rs +++ b/bitcoin/src/hash_types.rs @@ -46,7 +46,7 @@ macro_rules! impl_asref_push_bytes { )* }; } - +pub(crate) use impl_asref_push_bytes; // newtypes module is solely here so we can rustfmt::skip. pub use newtypes::*; @@ -69,12 +69,8 @@ mod newtypes { /// A bitcoin block hash. pub struct BlockHash(sha256d::Hash); - /// A hash of a public key. - pub struct PubkeyHash(hash160::Hash); /// A hash of Bitcoin Script bytecode. pub struct ScriptHash(hash160::Hash); - /// SegWit version of a public key hash. - pub struct WPubkeyHash(hash160::Hash); /// SegWit version of a Bitcoin Script bytecode hash. pub struct WScriptHash(sha256::Hash); @@ -103,5 +99,5 @@ mod newtypes { impl_hashencode!(FilterHash); impl_hashencode!(FilterHeader); - impl_asref_push_bytes!(PubkeyHash, ScriptHash, WPubkeyHash, WScriptHash); + impl_asref_push_bytes!(ScriptHash, WScriptHash); } diff --git a/bitcoin/src/lib.rs b/bitcoin/src/lib.rs index 0665662a..5eb52b07 100644 --- a/bitcoin/src/lib.rs +++ b/bitcoin/src/lib.rs @@ -141,11 +141,9 @@ pub use crate::blockdata::weight::Weight; pub use crate::blockdata::witness::{self, Witness}; pub use crate::blockdata::{constants, opcodes}; pub use crate::consensus::encode::VarInt; -pub use crate::crypto::key::{self, PrivateKey, PublicKey}; +pub use crate::crypto::key::{self, PrivateKey, PubkeyHash, PublicKey, WPubkeyHash}; pub use crate::crypto::{ecdsa, sighash}; -pub use crate::hash_types::{ - BlockHash, PubkeyHash, ScriptHash, Txid, WPubkeyHash, WScriptHash, Wtxid, -}; +pub use crate::hash_types::{BlockHash, ScriptHash, Txid, WScriptHash, Wtxid}; pub use crate::merkle_tree::MerkleBlock; pub use crate::network::Network; pub use crate::pow::{CompactTarget, Target, Work}; From 27b3c1e0e6bc192412e1c625d913b3e2651167e6 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Fri, 23 Jun 2023 13:23:19 +1000 Subject: [PATCH 2/2] Improve the ScriptHash and WScriptHash types Improve the script hash types by doing: - Define the types in the `crypto::script` module - Put the From impls directly below the type definitions Keep the current crate level re-export so this does not impact the public API _if_ people are using the re-export but is still a breaking change. --- bitcoin/src/address.rs | 3 +- bitcoin/src/blockdata/script/borrowed.rs | 2 +- bitcoin/src/blockdata/script/mod.rs | 58 ++++++++++++++---------- bitcoin/src/blockdata/script/owned.rs | 5 +- bitcoin/src/hash_types.rs | 9 +--- bitcoin/src/lib.rs | 4 +- 6 files changed, 41 insertions(+), 40 deletions(-) diff --git a/bitcoin/src/address.rs b/bitcoin/src/address.rs index e05fe9ea..81354dee 100644 --- a/bitcoin/src/address.rs +++ b/bitcoin/src/address.rs @@ -43,9 +43,8 @@ use crate::blockdata::constants::{ }; use crate::blockdata::script::witness_program::{self, WitnessProgram}; use crate::blockdata::script::witness_version::{self, WitnessVersion}; -use crate::blockdata::script::{self, Script, ScriptBuf}; +use crate::blockdata::script::{self, Script, ScriptBuf, ScriptHash}; use crate::crypto::key::{PubkeyHash, PublicKey, TapTweak, TweakedPublicKey, UntweakedPublicKey}; -use crate::hash_types::ScriptHash; use crate::network::Network; use crate::prelude::*; use crate::taproot::TapNodeHash; diff --git a/bitcoin/src/blockdata/script/borrowed.rs b/bitcoin/src/blockdata/script/borrowed.rs index 9fd12b27..64a57abc 100644 --- a/bitcoin/src/blockdata/script/borrowed.rs +++ b/bitcoin/src/blockdata/script/borrowed.rs @@ -14,9 +14,9 @@ use crate::blockdata::opcodes::{self}; use crate::blockdata::script::witness_version::WitnessVersion; use crate::blockdata::script::{ bytes_to_asm_fmt, Builder, Instruction, InstructionIndices, Instructions, ScriptBuf, + ScriptHash, WScriptHash, }; use crate::consensus::Encodable; -use crate::hash_types::{ScriptHash, WScriptHash}; use crate::key::{PublicKey, UntweakedPublicKey}; use crate::policy::DUST_RELAY_TX_FEE; use crate::prelude::*; diff --git a/bitcoin/src/blockdata/script/mod.rs b/bitcoin/src/blockdata/script/mod.rs index ee45ed45..2a341eef 100644 --- a/bitcoin/src/blockdata/script/mod.rs +++ b/bitcoin/src/blockdata/script/mod.rs @@ -55,13 +55,13 @@ use core::cmp::Ordering; use core::fmt; use core::ops::{Deref, DerefMut}; +use hashes::{hash160, sha256}; #[cfg(feature = "serde")] use serde; use crate::blockdata::opcodes::all::*; use crate::blockdata::opcodes::{self}; use crate::consensus::{encode, Decodable, Encodable}; -use crate::hash_types::{ScriptHash, WScriptHash}; use crate::prelude::*; use crate::{io, OutPoint}; @@ -81,6 +81,38 @@ pub use self::instruction::*; pub use self::owned::*; pub use self::push_bytes::*; +hashes::hash_newtype! { + /// A hash of Bitcoin Script bytecode. + pub struct ScriptHash(hash160::Hash); + /// SegWit version of a Bitcoin Script bytecode hash. + pub struct WScriptHash(sha256::Hash); +} +crate::hash_types::impl_asref_push_bytes!(ScriptHash, WScriptHash); + +impl From for ScriptHash { + fn from(script: ScriptBuf) -> ScriptHash { script.script_hash() } +} + +impl From<&ScriptBuf> for ScriptHash { + fn from(script: &ScriptBuf) -> ScriptHash { script.script_hash() } +} + +impl From<&Script> for ScriptHash { + fn from(script: &Script) -> ScriptHash { script.script_hash() } +} + +impl From for WScriptHash { + fn from(script: ScriptBuf) -> WScriptHash { script.wscript_hash() } +} + +impl From<&ScriptBuf> for WScriptHash { + fn from(script: &ScriptBuf) -> WScriptHash { script.wscript_hash() } +} + +impl From<&Script> for WScriptHash { + fn from(script: &Script) -> WScriptHash { script.wscript_hash() } +} + /// Encodes an integer in script(minimal CScriptNum) format. /// /// Writes bytes into the buffer and returns the number of bytes written. @@ -304,30 +336,6 @@ impl From for Vec { fn from(v: ScriptBuf) -> Self { v.0 } } -impl From for ScriptHash { - fn from(script: ScriptBuf) -> ScriptHash { script.script_hash() } -} - -impl From<&ScriptBuf> for ScriptHash { - fn from(script: &ScriptBuf) -> ScriptHash { script.script_hash() } -} - -impl From<&Script> for ScriptHash { - fn from(script: &Script) -> ScriptHash { script.script_hash() } -} - -impl From for WScriptHash { - fn from(script: ScriptBuf) -> WScriptHash { script.wscript_hash() } -} - -impl From<&ScriptBuf> for WScriptHash { - fn from(script: &ScriptBuf) -> WScriptHash { script.wscript_hash() } -} - -impl From<&Script> for WScriptHash { - fn from(script: &Script) -> WScriptHash { script.wscript_hash() } -} - impl AsRef