bobcat_cd/
lib.rs

1#![no_std]
2
3pub use bobcat_maths::U;
4
5pub use bobcat_storage::const_keccak256;
6
7use array_concat::concat_arrays;
8
9#[macro_export]
10macro_rules! read_word_slices {
11    ($slice:expr, 1) => {{
12        let s = $slice;
13        assert!(s.len() >= 32);
14        &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) })
15    }};
16    ($slice:expr, 2) => {{
17        let s = $slice;
18        assert!(s.len() >= 64);
19        (
20            &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
21            &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
22        )
23    }};
24    ($slice:expr, 3) => {{
25        let s = $slice;
26        assert!(s.len() >= 96);
27        (
28            &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
29            &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
30            &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
31        )
32    }};
33    ($slice:expr, 4) => {{
34        let s = $slice;
35        assert!(s.len() >= 128);
36        (
37            &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
38            &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
39            &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
40            &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
41        )
42    }};
43    ($slice:expr, 5) => {{
44        let s = $slice;
45        assert!(s.len() >= 160);
46        (
47            &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
48            &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
49            &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
50            &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
51            &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
52        )
53    }};
54    ($slice:expr, 6) => {{
55        let s = $slice;
56        assert!(s.len() >= 192);
57        (
58            &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
59            &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
60            &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
61            &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
62            &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
63            &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
64        )
65    }};
66    ($slice:expr, 7) => {{
67        let s = $slice;
68        assert!(s.len() >= 224);
69        (
70            &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
71            &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
72            &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
73            &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
74            &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
75            &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
76            &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
77        )
78    }};
79    ($slice:expr, 8) => {{
80        let s = $slice;
81        assert!(s.len() >= 256);
82        (
83            &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
84            &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
85            &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
86            &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
87            &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
88            &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
89            &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
90            &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
91        )
92    }};
93    ($slice:expr, 9) => {{
94        let s = $slice;
95        assert!(s.len() >= 288);
96        (
97            &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
98            &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
99            &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
100            &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
101            &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
102            &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
103            &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
104            &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
105            &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
106        )
107    }};
108    ($slice:expr, 10) => {{
109        let s = $slice;
110        assert!(s.len() >= 320);
111        (
112            &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
113            &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
114            &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
115            &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
116            &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
117            &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
118            &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
119            &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
120            &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
121            &U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
122        )
123    }};
124    ($slice:expr, 11) => {{
125        let s = $slice;
126        assert!(s.len() >= 352);
127        (
128            &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
129            &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
130            &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
131            &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
132            &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
133            &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
134            &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
135            &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
136            &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
137            &U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
138            &U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
139        )
140    }};
141    ($slice:expr, 12) => {{
142        let s = $slice;
143        assert!(s.len() >= 384);
144        (
145            &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
146            &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
147            &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
148            &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
149            &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
150            &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
151            &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
152            &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
153            &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
154            &U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
155            &U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
156            &U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
157        )
158    }};
159    ($slice:expr, 13) => {{
160        let s = $slice;
161        assert!(s.len() >= 416);
162        (
163            &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
164            &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
165            &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
166            &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
167            &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
168            &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
169            &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
170            &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
171            &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
172            &U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
173            &U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
174            &U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
175            &U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
176        )
177    }};
178    ($slice:expr, 14) => {{
179        let s = $slice;
180        assert!(s.len() >= 448);
181        (
182            &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
183            &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
184            &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
185            &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
186            &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
187            &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
188            &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
189            &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
190            &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
191            &U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
192            &U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
193            &U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
194            &U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
195            &U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
196        )
197    }};
198    ($slice:expr, 15) => {{
199        let s = $slice;
200        assert!(s.len() >= 480);
201        (
202            &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
203            &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
204            &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
205            &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
206            &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
207            &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
208            &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
209            &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
210            &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
211            &U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
212            &U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
213            &U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
214            &U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
215            &U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
216            &U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
217        )
218    }};
219    ($slice:expr, 16) => {{
220        let s = $slice;
221        assert!(s.len() >= 512);
222        (
223            &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
224            &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
225            &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
226            &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
227            &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
228            &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
229            &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
230            &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
231            &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
232            &U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
233            &U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
234            &U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
235            &U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
236            &U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
237            &U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
238            &U::from(unsafe { *(s[48..512].as_ptr() as *const [u8; 32]) }),
239        )
240    }};
241    ($slice:expr, 17) => {{
242        let s = $slice;
243        assert!(s.len() >= 544);
244        (
245            &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
246            &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
247            &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
248            &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
249            &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
250            &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
251            &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
252            &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
253            &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
254            &U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
255            &U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
256            &U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
257            &U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
258            &U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
259            &U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
260            &U::from(unsafe { *(s[48..512].as_ptr() as *const [u8; 32]) }),
261            &U::from(unsafe { *(s[512..544].as_ptr() as *const [u8; 32]) }),
262        )
263    }};
264    ($slice:expr, 18) => {{
265        let s = $slice;
266        assert!(s.len() >= 576);
267        (
268            &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
269            &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
270            &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
271            &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
272            &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
273            &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
274            &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
275            &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
276            &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
277            &U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
278            &U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
279            &U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
280            &U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
281            &U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
282            &U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
283            &U::from(unsafe { *(s[48..512].as_ptr() as *const [u8; 32]) }),
284            &U::from(unsafe { *(s[512..544].as_ptr() as *const [u8; 32]) }),
285            &U::from(unsafe { *(s[544..576].as_ptr() as *const [u8; 32]) }),
286        )
287    }};
288    ($slice:expr, 19) => {{
289        let s = $slice;
290        assert!(s.len() >= 608);
291        (
292            &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
293            &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
294            &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
295            &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
296            &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
297            &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
298            &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
299            &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
300            &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
301            &U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
302            &U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
303            &U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
304            &U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
305            &U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
306            &U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
307            &U::from(unsafe { *(s[48..512].as_ptr() as *const [u8; 32]) }),
308            &U::from(unsafe { *(s[512..544].as_ptr() as *const [u8; 32]) }),
309            &U::from(unsafe { *(s[544..576].as_ptr() as *const [u8; 32]) }),
310            &U::from(unsafe { *(s[576..608].as_ptr() as *const [u8; 32]) }),
311        )
312    }};
313    ($slice:expr, 20) => {{
314        let s = $slice;
315        assert!(s.len() >= 640);
316        (
317            &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
318            &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
319            &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
320            &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
321            &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
322            &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
323            &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
324            &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
325            &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
326            &U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
327            &U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
328            &U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
329            &U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
330            &U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
331            &U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
332            &U::from(unsafe { *(s[48..512].as_ptr() as *const [u8; 32]) }),
333            &U::from(unsafe { *(s[512..544].as_ptr() as *const [u8; 32]) }),
334            &U::from(unsafe { *(s[544..576].as_ptr() as *const [u8; 32]) }),
335            &U::from(unsafe { *(s[576..608].as_ptr() as *const [u8; 32]) }),
336            &U::from(unsafe { *(s[608..640].as_ptr() as *const [u8; 32]) }),
337        )
338    }};
339}
340
341pub const fn leftpad_addr(x: [u8; 20]) -> [u8; 32] {
342    concat_arrays!([0u8; 32 - 20], x)
343}
344
345pub const fn leftpad_u8(x: u8) -> [u8; 32] {
346    concat_arrays!([0u8; 32 - 1], [x])
347}
348
349pub const fn const_keccak_sel(x: &[u8]) -> [u8; 4] {
350    let x = const_keccak256(x).0;
351    [x[0], x[1], x[2], x[3]]
352}
353
354#[test]
355fn test_access() {
356    use bobcat_maths::Address;
357    let cd = const_hex::const_decode_to_array::<{ 32 * 2 + 4 }>(b"a9059cbb0000000000000000000000006221a9c005f6e47eb398fd867784cacfdcfff4e7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap();
358    let a = const_hex::const_decode_to_array::<20>(b"6221a9c005f6e47eb398fd867784cacfdcfff4e7")
359        .unwrap();
360    let (addr, amt) = read_word_slices!(&cd[4..], 2);
361    assert_eq!((a, U::MAX), (Address::from(U::from(*addr)), U::from(*amt)));
362}