1use std::cmp::Ordering;
2use std::fmt;
3use std::str::FromStr;
4
5use serde::de::{self, Visitor};
6use serde::{Deserialize, Deserializer, Serialize, Serializer};
7
8#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
9pub enum ParseError {
10 #[error("missing 0x prefix in `{0}`")]
11 MissingPrefix(String),
12 #[error("invalid hex in `{0}`")]
13 InvalidHex(String),
14 #[error("`{input}` is not {expected} bytes")]
15 WrongLength { input: String, expected: usize },
16 #[error("`{0}` does not fit in 256 bits")]
17 Overflow(String),
18 #[error("invalid decimal number `{0}`")]
19 InvalidDecimal(String),
20}
21
22pub(crate) fn decode_hex(s: &str) -> Result<Vec<u8>, ParseError> {
23 let digits = s
24 .strip_prefix("0x")
25 .or_else(|| s.strip_prefix("0X"))
26 .ok_or_else(|| ParseError::MissingPrefix(s.into()))?;
27 let padded;
28 let digits = if digits.len() % 2 == 1 {
29 padded = format!("0{digits}");
30 padded.as_str()
31 } else {
32 digits
33 };
34 digits
35 .as_bytes()
36 .chunks(2)
37 .map(|pair| {
38 let hi = (pair[0] as char).to_digit(16);
39 let lo = (pair[1] as char).to_digit(16);
40 match (hi, lo) {
41 (Some(h), Some(l)) => Ok((h * 16 + l) as u8),
42 _ => Err(ParseError::InvalidHex(s.into())),
43 }
44 })
45 .collect()
46}
47
48pub(crate) fn encode_hex(bytes: &[u8]) -> String {
49 const DIGITS: &[u8; 16] = b"0123456789abcdef";
50 let mut out = String::with_capacity(2 + bytes.len() * 2);
51 out.push_str("0x");
52 for b in bytes {
53 out.push(DIGITS[(b >> 4) as usize] as char);
54 out.push(DIGITS[(b & 0xf) as usize] as char);
55 }
56 out
57}
58
59macro_rules! fixed_bytes {
60 ($name:ident, $len:expr) => {
61 #[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
62 pub struct $name(pub [u8; $len]);
63
64 impl $name {
65 pub const ZERO: Self = Self([0; $len]);
66
67 pub fn is_zero(&self) -> bool {
68 self.0 == [0; $len]
69 }
70 }
71
72 impl FromStr for $name {
73 type Err = ParseError;
74
75 fn from_str(s: &str) -> Result<Self, ParseError> {
76 let bytes = decode_hex(s)?;
77 let array = bytes
78 .try_into()
79 .map_err(|_| ParseError::WrongLength { input: s.into(), expected: $len })?;
80 Ok(Self(array))
81 }
82 }
83
84 impl fmt::Display for $name {
85 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86 f.write_str(&encode_hex(&self.0))
87 }
88 }
89
90 impl fmt::Debug for $name {
91 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92 fmt::Display::fmt(self, f)
93 }
94 }
95
96 impl Serialize for $name {
97 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
98 s.serialize_str(&self.to_string())
99 }
100 }
101
102 impl<'de> Deserialize<'de> for $name {
103 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
104 let s = String::deserialize(d)?;
105 s.parse().map_err(de::Error::custom)
106 }
107 }
108 };
109}
110
111fixed_bytes!(Address, 20);
112fixed_bytes!(B256, 32);
113
114impl B256 {
115 pub fn from_word(s: &str) -> Result<Self, ParseError> {
117 let bytes = decode_hex(s)?;
118 if bytes.len() > 32 {
119 return Err(ParseError::WrongLength { input: s.into(), expected: 32 });
120 }
121 let mut out = [0u8; 32];
122 out[32 - bytes.len()..].copy_from_slice(&bytes);
123 Ok(Self(out))
124 }
125}
126
127pub const EMPTY_CODE_HASH: B256 = B256([
129 0xc5, 0xd2, 0x46, 0x01, 0x86, 0xf7, 0x23, 0x3c, 0x92, 0x7e, 0x7d, 0xb2, 0xdc, 0xc7, 0x03, 0xc0, 0xe5,
130 0x00, 0xb6, 0x53, 0xca, 0x82, 0x27, 0x3b, 0x7b, 0xfa, 0xd8, 0x04, 0x5d, 0x85, 0xa4, 0x70,
131]);
132
133#[derive(Clone, Default, PartialEq, Eq, Hash)]
135pub struct Bytes(pub Vec<u8>);
136
137impl Bytes {
138 pub fn len(&self) -> usize {
139 self.0.len()
140 }
141
142 pub fn is_empty(&self) -> bool {
143 self.0.is_empty()
144 }
145}
146
147impl fmt::Display for Bytes {
148 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
149 f.write_str(&encode_hex(&self.0))
150 }
151}
152
153impl fmt::Debug for Bytes {
154 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
155 write!(f, "Bytes({} bytes)", self.0.len())
156 }
157}
158
159impl Serialize for Bytes {
160 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
161 s.serialize_str(&self.to_string())
162 }
163}
164
165impl<'de> Deserialize<'de> for Bytes {
166 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
167 let s = String::deserialize(d)?;
168 decode_hex(&s).map(Bytes).map_err(de::Error::custom)
169 }
170}
171
172#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)]
174pub struct U256([u64; 4]);
175
176impl U256 {
177 pub const ZERO: Self = Self([0; 4]);
178 pub const MAX: Self = Self([u64::MAX; 4]);
179
180 pub fn from_u128(v: u128) -> Self {
181 Self([v as u64, (v >> 64) as u64, 0, 0])
182 }
183
184 pub fn is_zero(&self) -> bool {
185 self.0 == [0; 4]
186 }
187
188 pub fn from_be_slice(bytes: &[u8]) -> Option<Self> {
189 let trimmed = &bytes[bytes.iter().position(|&b| b != 0).unwrap_or(bytes.len())..];
190 if trimmed.len() > 32 {
191 return None;
192 }
193 let mut word = [0u8; 32];
194 word[32 - trimmed.len()..].copy_from_slice(trimmed);
195 let mut limbs = [0u64; 4];
196 for (i, limb) in limbs.iter_mut().enumerate() {
197 let start = 32 - 8 * (i + 1);
198 *limb = u64::from_be_bytes(word[start..start + 8].try_into().expect("8 bytes"));
199 }
200 Some(Self(limbs))
201 }
202
203 pub fn to_be_bytes(self) -> [u8; 32] {
204 let mut out = [0u8; 32];
205 for (i, limb) in self.0.iter().enumerate() {
206 let start = 32 - 8 * (i + 1);
207 out[start..start + 8].copy_from_slice(&limb.to_be_bytes());
208 }
209 out
210 }
211
212 pub fn from_hex(s: &str) -> Result<Self, ParseError> {
213 let bytes = decode_hex(s)?;
214 Self::from_be_slice(&bytes).ok_or_else(|| ParseError::Overflow(s.into()))
215 }
216
217 pub fn from_dec(s: &str) -> Result<Self, ParseError> {
218 if s.is_empty() || !s.bytes().all(|b| b.is_ascii_digit()) {
219 return Err(ParseError::InvalidDecimal(s.into()));
220 }
221 let mut out = Self::ZERO;
222 for b in s.bytes() {
223 out = out
224 .checked_mul_small(10)
225 .and_then(|v| v.checked_add(Self::from_u128(u128::from(b - b'0'))))
226 .ok_or_else(|| ParseError::Overflow(s.into()))?;
227 }
228 Ok(out)
229 }
230
231 pub fn checked_add(self, rhs: Self) -> Option<Self> {
232 let mut out = [0u64; 4];
233 let mut carry = false;
234 for (o, (a, b)) in out.iter_mut().zip(self.0.iter().zip(rhs.0)) {
235 let (s1, c1) = a.overflowing_add(b);
236 let (s2, c2) = s1.overflowing_add(u64::from(carry));
237 *o = s2;
238 carry = c1 || c2;
239 }
240 (!carry).then_some(Self(out))
241 }
242
243 pub fn checked_sub(self, rhs: Self) -> Option<Self> {
244 let mut out = [0u64; 4];
245 let mut borrow = false;
246 for (o, (a, b)) in out.iter_mut().zip(self.0.iter().zip(rhs.0)) {
247 let (d1, b1) = a.overflowing_sub(b);
248 let (d2, b2) = d1.overflowing_sub(u64::from(borrow));
249 *o = d2;
250 borrow = b1 || b2;
251 }
252 (!borrow).then_some(Self(out))
253 }
254
255 fn checked_mul_small(self, m: u64) -> Option<Self> {
256 let mut out = [0u64; 4];
257 let mut carry = 0u128;
258 for (o, a) in out.iter_mut().zip(self.0) {
259 let v = u128::from(a) * u128::from(m) + carry;
260 *o = v as u64;
261 carry = v >> 64;
262 }
263 (carry == 0).then_some(Self(out))
264 }
265
266 fn div_rem_small(self, d: u64) -> (Self, u64) {
267 let mut out = [0u64; 4];
268 let mut rem = 0u128;
269 for i in (0..4).rev() {
270 let v = (rem << 64) | u128::from(self.0[i]);
271 out[i] = (v / u128::from(d)) as u64;
272 rem = v % u128::from(d);
273 }
274 (Self(out), rem as u64)
275 }
276
277 pub fn to_hex_quantity(self) -> String {
278 if self.is_zero() {
279 return "0x0".into();
280 }
281 let hex = encode_hex(&self.to_be_bytes());
282 format!("0x{}", hex[2..].trim_start_matches('0'))
283 }
284
285 pub fn format_ether(self) -> String {
287 let s = self.to_string();
288 let (int, frac) = if s.len() > 18 { s.split_at(s.len() - 18) } else { ("0", s.as_str()) };
289 let frac = format!("{frac:0>18}");
290 let frac = frac.trim_end_matches('0');
291 if frac.is_empty() { int.to_string() } else { format!("{int}.{frac}") }
292 }
293}
294
295impl Ord for U256 {
296 fn cmp(&self, other: &Self) -> Ordering {
297 self.0.iter().rev().cmp(other.0.iter().rev())
298 }
299}
300
301impl PartialOrd for U256 {
302 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
303 Some(self.cmp(other))
304 }
305}
306
307impl fmt::Display for U256 {
308 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
309 if self.is_zero() {
310 return f.write_str("0");
311 }
312 let mut digits = Vec::new();
313 let mut v = *self;
314 while !v.is_zero() {
315 let (q, r) = v.div_rem_small(10);
316 digits.push(b'0' + r as u8);
317 v = q;
318 }
319 digits.reverse();
320 f.write_str(std::str::from_utf8(&digits).expect("ascii"))
321 }
322}
323
324impl fmt::Debug for U256 {
325 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
326 fmt::Display::fmt(self, f)
327 }
328}
329
330impl FromStr for U256 {
331 type Err = ParseError;
332
333 fn from_str(s: &str) -> Result<Self, ParseError> {
335 if s.starts_with("0x") || s.starts_with("0X") { Self::from_hex(s) } else { Self::from_dec(s) }
336 }
337}
338
339impl Serialize for U256 {
340 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
341 s.serialize_str(&self.to_string())
342 }
343}
344
345impl<'de> Deserialize<'de> for U256 {
347 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
348 struct V;
349 impl Visitor<'_> for V {
350 type Value = U256;
351
352 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
353 f.write_str("a hex or decimal quantity")
354 }
355
356 fn visit_u64<E: de::Error>(self, v: u64) -> Result<U256, E> {
357 Ok(U256::from_u128(u128::from(v)))
358 }
359
360 fn visit_str<E: de::Error>(self, v: &str) -> Result<U256, E> {
361 v.parse().map_err(E::custom)
362 }
363 }
364 d.deserialize_any(V)
365 }
366}
367
368pub(crate) fn de_quantity_u64<'de, D: Deserializer<'de>>(d: D) -> Result<Option<u64>, D::Error> {
370 let v = Option::<U256>::deserialize(d)?;
371 v.map(|v| {
372 let limbs = v.0;
373 if limbs[1..] == [0, 0, 0] { Ok(limbs[0]) } else { Err(de::Error::custom("nonce exceeds 64 bits")) }
374 })
375 .transpose()
376}
377
378#[derive(Clone, Copy, Debug, PartialEq, Eq)]
380pub struct Delta {
381 pub negative: bool,
382 pub magnitude: U256,
383}
384
385impl Delta {
386 pub fn between(from: U256, to: U256) -> Self {
387 match to.checked_sub(from) {
388 Some(m) => Self { negative: false, magnitude: m },
389 None => Self { negative: true, magnitude: from.checked_sub(to).expect("from > to") },
390 }
391 }
392
393 fn sign(&self) -> &'static str {
394 if self.magnitude.is_zero() {
395 ""
396 } else if self.negative {
397 "-"
398 } else {
399 "+"
400 }
401 }
402
403 pub fn format_ether(&self) -> String {
404 format!("{}{}", self.sign(), self.magnitude.format_ether())
405 }
406}
407
408impl fmt::Display for Delta {
409 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
410 write!(f, "{}{}", self.sign(), self.magnitude)
411 }
412}
413
414#[cfg(test)]
415mod tests {
416 use super::*;
417
418 #[test]
419 fn address_round_trip() {
420 let a: Address = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8".parse().unwrap();
421 assert_eq!(a.to_string(), "0x70997970c51812dc3a010c7d01b50e0d17dc79c8");
422 assert!("70997970c51812dc3a010c7d01b50e0d17dc79c8".parse::<Address>().is_err());
423 assert!("0x1234".parse::<Address>().is_err());
424 assert!("0xzz997970c51812dc3a010c7d01b50e0d17dc79c8".parse::<Address>().is_err());
425 }
426
427 #[test]
428 fn u256_parsing_and_display() {
429 let max = "115792089237316195423570985008687907853269984665640564039457584007913129639935";
430 assert_eq!(U256::from_dec(max).unwrap(), U256::MAX);
431 assert_eq!(U256::MAX.to_string(), max);
432 assert_eq!(U256::from_hex(&U256::MAX.to_hex_quantity()).unwrap(), U256::MAX);
433 assert_eq!("0x0".parse::<U256>().unwrap(), U256::ZERO);
434 assert_eq!("0xde0b6b3a7640000".parse::<U256>().unwrap().to_string(), "1000000000000000000");
435 assert!(U256::from_dec(&format!("{max}0")).is_err());
436 assert!(U256::from_hex(&format!("0x1{}", "0".repeat(64))).is_err());
437 assert_eq!(U256::ZERO.to_hex_quantity(), "0x0");
438 assert_eq!(U256::from_u128(255).to_hex_quantity(), "0xff");
439 }
440
441 #[test]
442 fn ether_formatting() {
443 assert_eq!(U256::from_dec("1000000000000000000").unwrap().format_ether(), "1");
444 assert_eq!(U256::from_dec("1500000000000000000").unwrap().format_ether(), "1.5");
445 assert_eq!(U256::from_u128(21000).format_ether(), "0.000000000000021");
446 assert_eq!(U256::ZERO.format_ether(), "0");
447 }
448
449 #[test]
450 fn deltas() {
451 let a = U256::from_u128(10);
452 let b = U256::from_u128(3);
453 assert_eq!(Delta::between(a, b).to_string(), "-7");
454 assert_eq!(Delta::between(b, a).to_string(), "+7");
455 assert_eq!(Delta::between(a, a).to_string(), "0");
456 assert!(U256::MAX.checked_add(U256::from_u128(1)).is_none());
457 assert!(U256::ZERO.checked_sub(U256::from_u128(1)).is_none());
458 assert!(U256::from_u128(1 << 64) > U256::from_u128(u64::MAX as u128));
459 }
460
461 #[test]
462 fn storage_words() {
463 assert_eq!(B256::from_word("0x7").unwrap().0[31], 7);
464 assert!(B256::from_word(&format!("0x{}", "11".repeat(33))).is_err());
465 }
466}