1#![cfg_attr(not(feature = "std"), no_std)]
2
3pub mod serialisation;
4
5pub use serialisation::{
6 EvmCdAddress, Error as EvmCdError, EvmCdArray, EvmCdArrayError, EvmCdDeserialise, EvmCdSerialise,
7 EvmCdString, EvmCdStringError, Read as EvmCdRead, Write as EvmCdWrite,
8};
9
10#[cfg(feature = "derive")]
11pub use bobcat_cd_derive::{EvmCdDeserialise, EvmCdSerialise};
12
13pub use bobcat_maths::U;
14
15pub use bobcat_storage::{const_keccak256, const_keccak256_two};
16
17pub use const_hex::const_decode_to_array as const_hex_decode_to_array;
18
19use array_concat::concat_arrays;
20
21#[cfg(feature = "alloc")]
22extern crate alloc;
23
24#[cfg(feature = "alloc")]
25use alloc::string::String;
26
27#[macro_export]
28macro_rules! address {
29 ($a:expr) => {{
30 match $crate::const_hex_decode_to_array::<20>($a) {
31 Ok(v) => v,
32 Err(_) => core::panic!("bad address"),
33 }
34 }};
35}
36
37#[macro_export]
38macro_rules! read_words {
39 ($slice:expr, 1) => {{
40 let s = $slice;
41 core::assert!(s.len() >= 32);
42 &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) })
43 }};
44 ($slice:expr, 2) => {{
45 let s = $slice;
46 core::assert!(s.len() >= 64);
47 (
48 &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
49 &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
50 )
51 }};
52 ($slice:expr, 3) => {{
53 let s = $slice;
54 core::assert!(s.len() >= 96);
55 (
56 &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
57 &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
58 &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
59 )
60 }};
61 ($slice:expr, 4) => {{
62 let s = $slice;
63 core::assert!(s.len() >= 128);
64 (
65 &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
66 &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
67 &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
68 &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
69 )
70 }};
71 ($slice:expr, 5) => {{
72 let s = $slice;
73 core::assert!(s.len() >= 160);
74 (
75 &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
76 &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
77 &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
78 &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
79 &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
80 )
81 }};
82 ($slice:expr, 6) => {{
83 let s = $slice;
84 core::assert!(s.len() >= 192);
85 (
86 &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
87 &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
88 &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
89 &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
90 &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
91 &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
92 )
93 }};
94 ($slice:expr, 7) => {{
95 let s = $slice;
96 core::assert!(s.len() >= 224);
97 (
98 &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
99 &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
100 &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
101 &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
102 &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
103 &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
104 &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
105 )
106 }};
107 ($slice:expr, 8) => {{
108 let s = $slice;
109 core::assert!(s.len() >= 256);
110 (
111 &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
112 &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
113 &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
114 &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
115 &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
116 &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
117 &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
118 &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
119 )
120 }};
121 ($slice:expr, 9) => {{
122 let s = $slice;
123 core::assert!(s.len() >= 288);
124 (
125 &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
126 &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
127 &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
128 &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
129 &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
130 &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
131 &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
132 &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
133 &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
134 )
135 }};
136 ($slice:expr, 10) => {{
137 let s = $slice;
138 core::assert!(s.len() >= 320);
139 (
140 &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
141 &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
142 &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
143 &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
144 &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
145 &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
146 &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
147 &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
148 &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
149 &$crate::U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
150 )
151 }};
152 ($slice:expr, 11) => {{
153 let s = $slice;
154 core::assert!(s.len() >= 352);
155 (
156 &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
157 &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
158 &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
159 &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
160 &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
161 &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
162 &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
163 &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
164 &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
165 &$crate::U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
166 &$crate::U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
167 )
168 }};
169 ($slice:expr, 12) => {{
170 let s = $slice;
171 core::assert!(s.len() >= 384);
172 (
173 &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
174 &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
175 &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
176 &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
177 &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
178 &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
179 &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
180 &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
181 &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
182 &$crate::U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
183 &$crate::U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
184 &$crate::U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
185 )
186 }};
187 ($slice:expr, 13) => {{
188 let s = $slice;
189 core::assert!(s.len() >= 416);
190 (
191 &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
192 &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
193 &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
194 &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
195 &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
196 &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
197 &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
198 &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
199 &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
200 &$crate::U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
201 &$crate::U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
202 &$crate::U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
203 &$crate::U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
204 )
205 }};
206 ($slice:expr, 14) => {{
207 let s = $slice;
208 core::assert!(s.len() >= 448);
209 (
210 &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
211 &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
212 &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
213 &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
214 &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
215 &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
216 &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
217 &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
218 &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
219 &$crate::U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
220 &$crate::U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
221 &$crate::U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
222 &$crate::U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
223 &$crate::U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
224 )
225 }};
226 ($slice:expr, 15) => {{
227 let s = $slice;
228 core::assert!(s.len() >= 480);
229 (
230 &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
231 &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
232 &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
233 &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
234 &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
235 &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
236 &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
237 &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
238 &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
239 &$crate::U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
240 &$crate::U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
241 &$crate::U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
242 &$crate::U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
243 &$crate::U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
244 &$crate::U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
245 )
246 }};
247 ($slice:expr, 16) => {{
248 let s = $slice;
249 core::assert!(s.len() >= 512);
250 (
251 &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
252 &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
253 &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
254 &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
255 &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
256 &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
257 &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
258 &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
259 &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
260 &$crate::U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
261 &$crate::U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
262 &$crate::U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
263 &$crate::U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
264 &$crate::U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
265 &$crate::U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
266 &$crate::U::from(unsafe { *(s[48..512].as_ptr() as *const [u8; 32]) }),
267 )
268 }};
269 ($slice:expr, 17) => {{
270 let s = $slice;
271 core::assert!(s.len() >= 544);
272 (
273 &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
274 &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
275 &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
276 &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
277 &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
278 &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
279 &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
280 &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
281 &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
282 &$crate::U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
283 &$crate::U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
284 &$crate::U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
285 &$crate::U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
286 &$crate::U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
287 &$crate::U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
288 &$crate::U::from(unsafe { *(s[48..512].as_ptr() as *const [u8; 32]) }),
289 &$crate::U::from(unsafe { *(s[512..544].as_ptr() as *const [u8; 32]) }),
290 )
291 }};
292 ($slice:expr, 18) => {{
293 let s = $slice;
294 core::assert!(s.len() >= 576);
295 (
296 &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
297 &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
298 &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
299 &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
300 &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
301 &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
302 &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
303 &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
304 &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
305 &$crate::U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
306 &$crate::U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
307 &$crate::U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
308 &$crate::U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
309 &$crate::U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
310 &$crate::U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
311 &$crate::U::from(unsafe { *(s[48..512].as_ptr() as *const [u8; 32]) }),
312 &$crate::U::from(unsafe { *(s[512..544].as_ptr() as *const [u8; 32]) }),
313 &$crate::U::from(unsafe { *(s[544..576].as_ptr() as *const [u8; 32]) }),
314 )
315 }};
316 ($slice:expr, 19) => {{
317 let s = $slice;
318 core::assert!(s.len() >= 608);
319 (
320 &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
321 &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
322 &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
323 &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
324 &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
325 &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
326 &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
327 &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
328 &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
329 &$crate::U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
330 &$crate::U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
331 &$crate::U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
332 &$crate::U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
333 &$crate::U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
334 &$crate::U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
335 &$crate::U::from(unsafe { *(s[48..512].as_ptr() as *const [u8; 32]) }),
336 &$crate::U::from(unsafe { *(s[512..544].as_ptr() as *const [u8; 32]) }),
337 &$crate::U::from(unsafe { *(s[544..576].as_ptr() as *const [u8; 32]) }),
338 &$crate::U::from(unsafe { *(s[576..608].as_ptr() as *const [u8; 32]) }),
339 )
340 }};
341 ($slice:expr, 20) => {{
342 let s = $slice;
343 core::assert!(s.len() >= 640);
344 (
345 &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
346 &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
347 &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
348 &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
349 &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
350 &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
351 &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
352 &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
353 &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
354 &$crate::U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
355 &$crate::U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
356 &$crate::U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
357 &$crate::U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
358 &$crate::U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
359 &$crate::U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
360 &$crate::U::from(unsafe { *(s[48..512].as_ptr() as *const [u8; 32]) }),
361 &$crate::U::from(unsafe { *(s[512..544].as_ptr() as *const [u8; 32]) }),
362 &$crate::U::from(unsafe { *(s[544..576].as_ptr() as *const [u8; 32]) }),
363 &$crate::U::from(unsafe { *(s[576..608].as_ptr() as *const [u8; 32]) }),
364 &$crate::U::from(unsafe { *(s[608..640].as_ptr() as *const [u8; 32]) }),
365 )
366 }};
367}
368
369pub const fn leftpad_bool(x: bool) -> [u8; 32] {
370 leftpad_u8(x as u8)
371}
372
373pub const fn leftpad_u24(x: [u8; 3]) -> [u8; 32] {
374 concat_arrays!([0u8; 32 - 3], x)
375}
376
377pub const fn leftpad_u8(x: u8) -> [u8; 32] {
378 concat_arrays!([0u8; 32 - 1], [x])
379}
380
381pub const fn rightpad_b8(x: [u8; 8]) -> [u8; 32] {
382 concat_arrays!(x, [0u8; 32 - 8])
383}
384
385pub const fn leftpad_addr(x: [u8; 20]) -> [u8; 32] {
386 concat_arrays!([0u8; 32 - 20], x)
387}
388
389pub const fn leftpad_u16(x: u16) -> [u8; 32] {
390 concat_arrays!([0u8; 32 - 2], x.to_be_bytes())
391}
392
393pub const fn leftpad_usize(x: usize) -> [u8; 32] {
394 concat_arrays!([0u8; 32 - core::mem::size_of::<usize>()], x.to_be_bytes())
395}
396
397pub const fn leftpad_u32(x: u32) -> [u8; 32] {
398 concat_arrays!([0u8; 32 - 4], x.to_be_bytes())
399}
400
401pub const fn const_keccak_sel(x: &[u8]) -> [u8; 4] {
402 let x = const_keccak256(x).0;
403 [x[0], x[1], x[2], x[3]]
404}
405
406pub const fn const_keccak_two_sel(x: &[u8], y: &[u8]) -> [u8; 4] {
407 let x = const_keccak256_two(x, y).0;
408 [x[0], x[1], x[2], x[3]]
409}
410
411pub fn decode_to_array(x: &[u8]) -> Option<&[u8]> {
412 if x.len() < 32 {
413 return None;
414 }
415 let offset = usize::from_be_bytes(x[32 - size_of::<usize>()..32].try_into().unwrap());
416 if x.len() < offset + 32 {
417 return None;
418 }
419 let len = usize::from_be_bytes(
420 x[offset + 32 - size_of::<usize>()..offset + 32]
421 .try_into()
422 .unwrap(),
423 );
424 let start = offset + 32;
425 let end = start.checked_add(len)?;
426 x.get(start..end)
427}
428
429pub fn decode_to_str(x: &[u8]) -> Option<&str> {
430 str::from_utf8(decode_to_array(x)?).ok()
431}
432
433#[cfg(feature = "alloc")]
434pub fn decode_to_string(x: &[u8]) -> Option<String> {
435 Some(String::from_utf8_lossy(decode_to_array(x)?).into_owned())
436}
437
438#[test]
439fn test_access() {
440 let cd = const_hex_decode_to_array::<{ 32 * 2 + 4 }>(b"a9059cbb0000000000000000000000006221a9c005f6e47eb398fd867784cacfdcfff4e7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap();
441 let a = const_hex_decode_to_array::<20>(b"6221a9c005f6e47eb398fd867784cacfdcfff4e7").unwrap();
442 let (addr, amt) = read_words!(&cd[4..], 2);
443 assert_eq!((a, U::MAX), (U::from(*addr).into(), U::from(*amt)));
444}
445
446#[test]
447fn test_address() {
448 address!(b"6221a9c005f6e47eb398fd867784cacfdcfff4e7");
449}
450
451#[cfg(all(test, feature = "proptest"))]
452mod test {
453 use proptest::prelude::*;
454
455 use super::*;
456
457 use alloc::string::String;
458
459 use alloy_sol_types::SolType;
460
461 proptest! {
462 #[test]
463 fn test_array_decoding(x in proptest::collection::vec(any::<u8>(), 1..20000usize)) {
464 let e = alloy_sol_types::sol_data::Bytes::abi_encode(&x);
465 assert_eq!(&x, decode_to_array(&e).unwrap());
466 }
467
468 #[test]
469 fn test_string_decoding(x in any::<String>()) {
470 let e = alloy_sol_types::sol_data::String::abi_encode(&x);
471 assert_eq!(x, decode_to_string(&e).unwrap());
472 assert_eq!(x, decode_to_str(&e).unwrap());
473 }
474 }
475}