aztec_core/abi/
selectors.rs1use ark_ff::{BigInteger, PrimeField};
2use serde::{Deserialize, Deserializer, Serialize, Serializer};
3use std::fmt;
4
5use super::types::{abi_type_signature, AbiParameter};
6use crate::hash::poseidon2_hash_bytes;
7use crate::types::Fr;
8use crate::Error;
9
10fn strip_0x(s: &str) -> &str {
11 s.strip_prefix("0x").unwrap_or(s)
12}
13
14fn decode_selector_hex(s: &str) -> Result<[u8; 4], Error> {
15 let raw = strip_0x(s);
16 if raw.len() > 8 {
17 return Err(Error::InvalidData(
18 "function selector must fit in 4 bytes".to_owned(),
19 ));
20 }
21 let padded = format!("{raw:0>8}");
22 let bytes = hex::decode(padded).map_err(|e| Error::InvalidData(e.to_string()))?;
23 let mut out = [0u8; 4];
24 out.copy_from_slice(&bytes);
25 Ok(out)
26}
27
28fn field_to_selector_bytes(field: Fr) -> [u8; 4] {
29 let raw = field.0.into_bigint().to_bytes_be();
30 let mut padded = [0u8; 32];
31 padded[32 - raw.len()..].copy_from_slice(&raw);
32 let mut out = [0u8; 4];
33 out.copy_from_slice(&padded[28..]);
34 out
35}
36
37fn selector_bytes_to_field(bytes: [u8; 4]) -> Fr {
38 Fr::from(u64::from(u32::from_be_bytes(bytes)))
39}
40
41fn selector_from_signature(signature: &str) -> [u8; 4] {
42 let hash = poseidon2_hash_bytes(signature.as_bytes());
43 field_to_selector_bytes(hash)
44}
45
46#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
48pub struct FunctionSelector(pub [u8; 4]);
49
50impl FunctionSelector {
51 pub fn from_hex(value: &str) -> Result<Self, Error> {
53 Ok(Self(decode_selector_hex(value)?))
54 }
55
56 pub fn from_field(field: Fr) -> Self {
58 Self(field_to_selector_bytes(field))
59 }
60
61 pub fn from_signature(signature: &str) -> Self {
72 Self(selector_from_signature(signature))
73 }
74
75 pub fn from_name_and_parameters(name: &str, params: &[AbiParameter]) -> Self {
80 let param_sigs: Vec<String> = params.iter().map(|p| abi_type_signature(&p.typ)).collect();
81 let sig = format!("{}({})", name, param_sigs.join(","));
82 Self::from_signature(&sig)
83 }
84
85 pub const fn empty() -> Self {
87 Self([0u8; 4])
88 }
89
90 pub fn to_field(self) -> Fr {
92 selector_bytes_to_field(self.0)
93 }
94}
95
96impl fmt::Display for FunctionSelector {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 write!(f, "0x{}", hex::encode(self.0))
99 }
100}
101
102impl Serialize for FunctionSelector {
103 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
104 where
105 S: Serializer,
106 {
107 serializer.serialize_str(&self.to_string())
108 }
109}
110
111impl<'de> Deserialize<'de> for FunctionSelector {
112 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
113 where
114 D: Deserializer<'de>,
115 {
116 let s = String::deserialize(deserializer)?;
117 Self::from_hex(&s).map_err(serde::de::Error::custom)
118 }
119}
120
121#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
123pub struct AuthorizationSelector(pub [u8; 4]);
124
125impl AuthorizationSelector {
126 pub fn from_hex(value: &str) -> Result<Self, Error> {
128 Ok(Self(decode_selector_hex(value)?))
129 }
130
131 pub fn from_field(field: Fr) -> Self {
133 Self(field_to_selector_bytes(field))
134 }
135
136 pub fn from_signature(signature: &str) -> Self {
138 Self(selector_from_signature(signature))
139 }
140
141 pub fn to_field(self) -> Fr {
143 selector_bytes_to_field(self.0)
144 }
145}
146
147impl fmt::Display for AuthorizationSelector {
148 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
149 write!(f, "0x{}", hex::encode(self.0))
150 }
151}
152
153impl Serialize for AuthorizationSelector {
154 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
155 where
156 S: Serializer,
157 {
158 serializer.serialize_str(&self.to_string())
159 }
160}
161
162impl<'de> Deserialize<'de> for AuthorizationSelector {
163 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
164 where
165 D: Deserializer<'de>,
166 {
167 let s = String::deserialize(deserializer)?;
168 Self::from_hex(&s).map_err(serde::de::Error::custom)
169 }
170}
171
172#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
174pub struct EventSelector(pub Fr);
175
176#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
181pub struct NoteSelector(pub u8);
182
183impl NoteSelector {
184 pub const MAX_VALUE: u8 = 127;
186
187 pub fn new(value: u8) -> Result<Self, Error> {
189 if value > Self::MAX_VALUE {
190 return Err(Error::InvalidData(format!(
191 "note selector must fit in 7 bits (got {})",
192 value
193 )));
194 }
195 Ok(Self(value))
196 }
197
198 pub fn empty() -> Self {
200 Self(0)
201 }
202
203 pub fn from_field(field: Fr) -> Result<Self, Error> {
205 let val = field.to_usize();
206 if val > Self::MAX_VALUE as usize {
207 return Err(Error::InvalidData(format!(
208 "note selector must fit in 7 bits (got {})",
209 val
210 )));
211 }
212 Ok(Self(val as u8))
213 }
214
215 pub fn to_field(self) -> Fr {
217 Fr::from(self.0 as u64)
218 }
219
220 pub fn from_hex(value: &str) -> Result<Self, Error> {
222 let raw = value.strip_prefix("0x").unwrap_or(value);
223 let val = u8::from_str_radix(raw, 16).map_err(|e| Error::InvalidData(e.to_string()))?;
224 Self::new(val)
225 }
226}
227
228impl fmt::Display for NoteSelector {
229 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
230 write!(f, "0x{:02x}", self.0)
231 }
232}
233
234impl Serialize for NoteSelector {
235 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
236 where
237 S: Serializer,
238 {
239 serializer.serialize_u8(self.0)
240 }
241}
242
243impl<'de> Deserialize<'de> for NoteSelector {
244 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
245 where
246 D: Deserializer<'de>,
247 {
248 let val = u8::deserialize(deserializer)?;
249 Self::new(val).map_err(serde::de::Error::custom)
250 }
251}