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