1use amplify::{Bytes20, Bytes32, Wrapper};
23use commit_verify::{DigestExt, Ripemd160, Sha256};
24
25use crate::{
26 CompressedPk, LegacyPk, RedeemScript, UncompressedPk, WitnessScript, LIB_NAME_BITCOIN,
27};
28
29#[derive(Wrapper, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, From)]
30#[wrapper(Index, RangeOps, AsSlice, BorrowSlice, Hex, Display, FromStr)]
31#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)]
32#[strict_type(lib = LIB_NAME_BITCOIN)]
33#[cfg_attr(
34 feature = "serde",
35 derive(Serialize, Deserialize),
36 serde(crate = "serde_crate", transparent)
37)]
38pub struct PubkeyHash(
39 #[from]
40 #[from([u8; 20])]
41 pub Bytes20,
42);
43
44impl From<PubkeyHash> for [u8; 20] {
45 fn from(value: PubkeyHash) -> Self { value.0.into_inner() }
46}
47
48impl From<CompressedPk> for PubkeyHash {
49 fn from(pk: CompressedPk) -> Self {
50 let mut engine = Sha256::default();
51 engine.input_raw(&pk.to_byte_array());
52 let mut engine2 = Ripemd160::default();
53 engine2.input_raw(&engine.finish());
54 Self(engine2.finish().into())
55 }
56}
57
58impl From<UncompressedPk> for PubkeyHash {
59 fn from(pk: UncompressedPk) -> Self {
60 let mut engine = Sha256::default();
61 engine.input_raw(&pk.to_byte_array());
62 let mut engine2 = Ripemd160::default();
63 engine2.input_raw(&engine.finish());
64 Self(engine2.finish().into())
65 }
66}
67
68impl From<LegacyPk> for PubkeyHash {
69 fn from(pk: LegacyPk) -> Self {
70 let mut engine = Sha256::default();
71 engine.input_raw(&pk.to_vec());
72 let mut engine2 = Ripemd160::default();
73 engine2.input_raw(&engine.finish());
74 Self(engine2.finish().into())
75 }
76}
77
78#[derive(Wrapper, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, From)]
79#[wrapper(Index, RangeOps, AsSlice, BorrowSlice, Hex, Display, FromStr)]
80#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)]
81#[strict_type(lib = LIB_NAME_BITCOIN)]
82#[cfg_attr(
83 feature = "serde",
84 derive(Serialize, Deserialize),
85 serde(crate = "serde_crate", transparent)
86)]
87pub struct ScriptHash(
88 #[from]
89 #[from([u8; 20])]
90 pub Bytes20,
91);
92
93impl From<ScriptHash> for [u8; 20] {
94 fn from(value: ScriptHash) -> Self { value.0.into_inner() }
95}
96
97impl From<&RedeemScript> for ScriptHash {
98 fn from(redeem_script: &RedeemScript) -> Self {
99 let mut engine = Sha256::default();
100 engine.input_raw(redeem_script.as_slice());
101 let mut engine2 = Ripemd160::default();
102 engine2.input_raw(&engine.finish());
103 Self(engine2.finish().into())
104 }
105}
106
107#[derive(Wrapper, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, From)]
108#[wrapper(Index, RangeOps, AsSlice, BorrowSlice, Hex, Display, FromStr)]
109#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)]
110#[strict_type(lib = LIB_NAME_BITCOIN)]
111#[cfg_attr(
112 feature = "serde",
113 derive(Serialize, Deserialize),
114 serde(crate = "serde_crate", transparent)
115)]
116pub struct WPubkeyHash(
117 #[from]
118 #[from([u8; 20])]
119 pub Bytes20,
120);
121
122impl From<WPubkeyHash> for [u8; 20] {
123 fn from(value: WPubkeyHash) -> Self { value.0.into_inner() }
124}
125
126impl From<CompressedPk> for WPubkeyHash {
127 fn from(pk: CompressedPk) -> Self {
128 let mut engine = Sha256::default();
129 engine.input_raw(&pk.to_byte_array());
130 let mut engine2 = Ripemd160::default();
131 engine2.input_raw(&engine.finish());
132 Self(engine2.finish().into())
133 }
134}
135
136#[derive(Wrapper, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, From)]
137#[wrapper(Index, RangeOps, AsSlice, BorrowSlice, Hex, Display, FromStr)]
138#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)]
139#[strict_type(lib = LIB_NAME_BITCOIN)]
140#[cfg_attr(
141 feature = "serde",
142 derive(Serialize, Deserialize),
143 serde(crate = "serde_crate", transparent)
144)]
145pub struct WScriptHash(
146 #[from]
147 #[from([u8; 32])]
148 pub Bytes32,
149);
150
151impl From<WScriptHash> for [u8; 32] {
152 fn from(value: WScriptHash) -> Self { value.0.into_inner() }
153}
154
155impl From<&WitnessScript> for WScriptHash {
156 fn from(witness_script: &WitnessScript) -> Self {
157 let mut engine = Sha256::default();
158 engine.input_raw(witness_script.as_slice());
159 let mut engine2 = Sha256::default();
160 engine2.input_raw(&engine.finish());
161 Self(engine2.finish().into())
162 }
163}