multiversx_chain_core/types/
address.rs1use super::H256;
2use alloc::{boxed::Box, vec::Vec};
3use core::fmt::Debug;
4
5const SC_ADDRESS_NUM_LEADING_ZEROS: u8 = 8;
6pub const NUM_INT_CHARACTERS_FOR_ADDRESS: usize = 10;
7pub const VM_TYPE_LEN: usize = 2;
8pub const DEFAULT_VM_TYPE: &[u8] = &[5, 0];
9
10#[derive(Hash, PartialEq, Eq, Clone, Debug)]
16pub struct Address(H256);
17
18impl Address {
19 pub const fn new(bytes: [u8; 32]) -> Self {
20 Address(H256::new(bytes))
21 }
22
23 pub fn generate_mock_address(creator_address: &[u8], creator_nonce: u64) -> Self {
24 let mut result = [0x00; 32];
25
26 result[10] = 0x11;
27 result[11] = 0x11;
28 result[12] = 0x11;
29 result[13] = 0x11;
30
31 result[14..29].copy_from_slice(&creator_address[..15]);
32 result[29] = creator_nonce as u8;
33 result[30..].copy_from_slice(&creator_address[30..]);
34
35 let start_index = NUM_INT_CHARACTERS_FOR_ADDRESS - VM_TYPE_LEN;
36 result[start_index..(start_index + DEFAULT_VM_TYPE.len())].copy_from_slice(DEFAULT_VM_TYPE);
37
38 Address::from(result)
39 }
40
41 #[cfg(feature = "std")]
42 pub fn to_bech32(&self, hrp: &str) -> crate::std::Bech32Address {
43 crate::std::Bech32Address::encode_address(hrp, self.clone())
44 }
45
46 #[cfg(feature = "std")]
47 pub fn to_bech32_default(&self) -> crate::std::Bech32Address {
48 crate::std::Bech32Address::encode_address_default_hrp(self.clone())
49 }
50
51 #[cfg(feature = "std")]
52 pub fn to_hex(&self) -> String {
53 self.0.to_hex()
54 }
55}
56
57impl From<H256> for Address {
58 #[inline]
59 fn from(hash: H256) -> Self {
60 Address(hash)
61 }
62}
63
64impl From<Address> for H256 {
65 #[inline]
66 fn from(address: Address) -> Self {
67 address.0
68 }
69}
70
71impl<'a> From<&'a Address> for &'a H256 {
72 #[inline]
73 fn from(address: &'a Address) -> Self {
74 &address.0
75 }
76}
77
78impl From<[u8; 32]> for Address {
79 #[inline]
80 fn from(arr: [u8; 32]) -> Self {
81 Address(H256::from(arr))
82 }
83}
84
85impl<'a> From<&'a [u8; 32]> for Address {
86 #[inline]
87 fn from(bytes: &'a [u8; 32]) -> Self {
88 Address(H256::from(bytes))
89 }
90}
91
92impl<'a> From<&'a mut [u8; 32]> for Address {
93 #[inline]
94 fn from(bytes: &'a mut [u8; 32]) -> Self {
95 Address(H256::from(bytes))
96 }
97}
98
99impl From<Box<[u8; 32]>> for Address {
100 #[inline]
101 fn from(bytes: Box<[u8; 32]>) -> Self {
102 Address(H256::from(bytes))
103 }
104}
105
106impl Address {
107 pub fn from_slice(slice: &[u8]) -> Self {
108 Address(H256::from_slice(slice))
109 }
110}
111
112impl From<Address> for [u8; 32] {
113 #[inline]
114 fn from(addr: Address) -> Self {
115 addr.0.into()
116 }
117}
118
119impl AsRef<[u8]> for Address {
120 #[inline]
121 fn as_ref(&self) -> &[u8] {
122 self.0.as_ref()
123 }
124}
125
126impl AsMut<[u8]> for Address {
127 #[inline]
128 fn as_mut(&mut self) -> &mut [u8] {
129 self.0.as_mut()
130 }
131}
132
133impl Address {
134 pub fn zero() -> Self {
138 Address(H256::zero())
139 }
140
141 #[inline]
143 pub fn len_bytes() -> usize {
144 H256::len_bytes()
145 }
146
147 #[inline]
149 pub fn as_bytes(&self) -> &[u8] {
150 self.0.as_bytes()
151 }
152
153 #[inline]
154 pub fn as_array(&self) -> &[u8; 32] {
155 self.0.as_array()
156 }
157
158 #[inline]
159 pub fn copy_to_array(&self, target: &mut [u8; 32]) {
160 self.0.copy_to_array(target)
161 }
162
163 #[inline]
164 pub fn to_vec(&self) -> Vec<u8> {
165 self.0.to_vec()
166 }
167
168 #[inline]
170 pub fn as_ptr(&self) -> *const u8 {
171 self.0.as_ptr()
172 }
173
174 #[inline]
177 pub fn as_mut_ptr(&mut self) -> *mut u8 {
178 self.0.as_mut_ptr()
179 }
180
181 pub fn is_zero(&self) -> bool {
183 self.0.is_zero()
184 }
185
186 pub fn is_smart_contract_address(&self) -> bool {
187 self.as_bytes()
188 .iter()
189 .take(SC_ADDRESS_NUM_LEADING_ZEROS.into())
190 .all(|item| item == &0u8)
191 }
192}
193
194use crate::codec::*;
195
196impl NestedEncode for Address {
197 fn dep_encode_or_handle_err<O, H>(&self, dest: &mut O, h: H) -> Result<(), H::HandledErr>
198 where
199 O: NestedEncodeOutput,
200 H: EncodeErrorHandler,
201 {
202 self.0.dep_encode_or_handle_err(dest, h)
203 }
204}
205
206impl TopEncode for Address {
207 fn top_encode_or_handle_err<O, H>(&self, output: O, h: H) -> Result<(), H::HandledErr>
208 where
209 O: TopEncodeOutput,
210 H: EncodeErrorHandler,
211 {
212 self.0.top_encode_or_handle_err(output, h)
213 }
214}
215
216impl NestedDecode for Address {
217 fn dep_decode_or_handle_err<I, H>(input: &mut I, h: H) -> Result<Self, H::HandledErr>
218 where
219 I: NestedDecodeInput,
220 H: DecodeErrorHandler,
221 {
222 Ok(Address(H256::dep_decode_or_handle_err(input, h)?))
223 }
224}
225
226impl TopDecode for Address {
227 fn top_decode_or_handle_err<I, H>(input: I, h: H) -> Result<Self, H::HandledErr>
228 where
229 I: TopDecodeInput,
230 H: DecodeErrorHandler,
231 {
232 Ok(Address(H256::top_decode_or_handle_err(input, h)?))
233 }
234}
235
236#[cfg(feature = "std")]
237impl core::fmt::Display for Address {
238 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
239 core::fmt::Display::fmt(&self.to_hex(), f)
240 }
241}
242
243#[cfg(test)]
244mod address_tests {
245 use super::*;
246 use crate::codec::test_util::{check_top_encode, check_top_encode_decode};
247 use alloc::vec::Vec;
248
249 #[test]
250 fn test_address() {
251 let addr = Address::from([4u8; 32]);
252 check_top_encode_decode(addr, &[4u8; 32]);
253 }
254
255 #[test]
256 fn test_opt_address() {
257 let addr = Address::from([4u8; 32]);
258 let mut expected: Vec<u8> = Vec::new();
259 expected.push(1u8);
260 expected.extend_from_slice(&[4u8; 32]);
261 check_top_encode_decode(Some(addr), expected.as_slice());
262 }
263
264 #[test]
265 fn test_ser_address_ref() {
266 let addr = Address::from([4u8; 32]);
267 let expected_bytes: &[u8] = &[4u8; 32 * 3];
268
269 let tuple = (&addr, &&&addr, addr.clone());
270 let serialized_bytes = check_top_encode(&tuple);
271 assert_eq!(serialized_bytes.as_slice(), expected_bytes);
272 }
273
274 #[test]
275 fn test_is_zero() {
276 assert!(Address::zero().is_zero());
277 }
278}