stratus/eth/primitives/
address.rs1use std::fmt::Display;
2use std::ops::Deref;
3use std::str::FromStr;
4
5use alloy_primitives::FixedBytes;
6use anyhow::anyhow;
7use display_json::DebugAsJson;
8use fake::Dummy;
9use fake::Faker;
10use hex_literal::hex;
11
12use crate::alias::RevmAddress;
13use crate::eth::primitives::LogTopic;
14
15#[derive(DebugAsJson, Clone, Copy, Default, Eq, PartialEq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize)]
17pub struct Address(pub FixedBytes<20>);
18
19impl Address {
20 pub const ZERO: Address = Address(FixedBytes::ZERO);
22
23 pub const COINBASE: Address = Address(FixedBytes(hex!("00000000000000000000000000000000000000ff")));
25 pub const BRLC: Address = Address(FixedBytes(hex!("a9a55a81a4c085ec0c31585aed4cfb09d78dfd53")));
26
27 pub const fn new(bytes: [u8; 20]) -> Self {
29 Self(FixedBytes(bytes))
30 }
31
32 pub fn is_zero(&self) -> bool {
34 self == &Self::ZERO
35 }
36
37 pub fn is_coinbase(&self) -> bool {
39 self == &Self::COINBASE
40 }
41
42 pub fn is_ignored(&self) -> bool {
47 self.is_coinbase() || self.is_zero()
48 }
49}
50
51impl Display for Address {
52 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53 write!(f, "{}", const_hex::encode_prefixed(self.0))
54 }
55}
56
57impl Dummy<Faker> for Address {
58 fn dummy_with_rng<R: rand::Rng + ?Sized>(_: &Faker, rng: &mut R) -> Self {
59 Address(FixedBytes::random_with(rng))
60 }
61}
62
63impl Deref for Address {
64 type Target = FixedBytes<20>;
65 fn deref(&self) -> &Self::Target {
66 &self.0
67 }
68}
69
70impl From<FixedBytes<20>> for Address {
75 fn from(value: FixedBytes<20>) -> Self {
76 Self(value)
77 }
78}
79
80impl From<[u8; 20]> for Address {
81 fn from(value: [u8; 20]) -> Self {
82 Self(FixedBytes::from(value))
83 }
84}
85
86impl From<RevmAddress> for Address {
87 fn from(value: RevmAddress) -> Self {
88 Address(value.0.0.into())
89 }
90}
91
92impl From<LogTopic> for Address {
93 fn from(value: LogTopic) -> Self {
94 Self(FixedBytes::from_slice(&value.0.0[12..32]))
95 }
96}
97
98impl TryFrom<Vec<u8>> for Address {
99 type Error = anyhow::Error;
100
101 fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
102 if value.len() != 20 {
103 return Err(anyhow!("array of bytes to be converted to address must have exactly 20 bytes"));
104 }
105 Ok(Self(FixedBytes::from_slice(&value)))
106 }
107}
108
109impl FromStr for Address {
132 type Err = anyhow::Error;
133
134 fn from_str(s: &str) -> Result<Self, Self::Err> {
135 Ok(Self(FixedBytes::from_str(s)?))
136 }
137}
138
139impl From<Address> for FixedBytes<20> {
140 fn from(value: Address) -> Self {
141 value.0
142 }
143}
144
145impl From<Address> for RevmAddress {
146 fn from(value: Address) -> Self {
147 revm::primitives::Address(value.0.0.into())
148 }
149}
150
151impl From<Address> for LogTopic {
152 fn from(value: Address) -> Self {
153 let padding = FixedBytes::<12>::ZERO;
154 Self(padding.concat_const(value.0))
155 }
156}