zink/primitives/
address.rs

1use crate::{
2    asm,
3    primitives::{Bytes20, Bytes32},
4    storage::Value,
5};
6
7/// Account address
8#[repr(C)]
9#[derive(Clone, Copy)]
10pub struct Address(Bytes20);
11
12impl Address {
13    /// Returns empty address
14    pub const fn empty() -> Self {
15        Address(Bytes20::empty())
16    }
17
18    /// Returns the caller address
19    #[inline(always)]
20    pub fn caller() -> Self {
21        unsafe { asm::evm::caller() }
22    }
23
24    /// if self equal to another
25    ///
26    /// NOTE: not using core::cmp because it uses registers in wasm
27    #[allow(clippy::should_implement_trait)]
28    #[inline(always)]
29    pub fn eq(self, other: Self) -> bool {
30        self.0.eq(other.0)
31    }
32
33    // Return Bytes32 for consistency with logN
34    pub fn to_bytes32(&self) -> Bytes32 {
35        #[cfg(target_family = "wasm")]
36        {
37            Bytes32(self.0 .0) // i32 in WASM
38        }
39        #[cfg(not(target_family = "wasm"))]
40        {
41            let mut bytes = [0u8; 32];
42            bytes[12..32].copy_from_slice(&self.0 .0); // [u8; 20] padded
43            Bytes32(bytes)
44        }
45    }
46
47    #[cfg(not(target_family = "wasm"))]
48    pub fn bytes32(&self) -> [u8; 32] {
49        self.to_bytes32().0 // Use to_bytes32 for non-WASM
50    }
51}
52
53impl Value for Address {
54    fn sload() -> Self {
55        Self(unsafe { asm::bytes::sload_bytes20() })
56    }
57
58    fn tload() -> Self {
59        Self(unsafe { asm::bytes::tload_bytes20() })
60    }
61
62    fn push(self) {
63        unsafe { asm::bytes::push_bytes20(self.0) }
64    }
65
66    #[cfg(not(target_family = "wasm"))]
67    fn bytes32(&self) -> [u8; 32] {
68        self.bytes32()
69    }
70}
71
72impl From<Bytes20> for Address {
73    fn from(value: Bytes20) -> Self {
74        Address(value)
75    }
76}
77
78#[cfg(not(target_family = "wasm"))]
79impl From<[u8; 20]> for Address {
80    fn from(value: [u8; 20]) -> Self {
81        Address(Bytes20(value))
82    }
83}