precompile_utils/solidity/codec/
native.rs1use super::*;
20use crate::solidity::revert::InjectBacktrace;
21use impl_trait_for_tuples::impl_for_tuples;
22use sp_core::{ConstU32, Get, H160};
23
24impl Codec for () {
25 fn read(_reader: &mut Reader) -> MayRevert<Self> {
26 Ok(())
27 }
28
29 fn write(_writer: &mut Writer, _value: Self) {}
30
31 fn has_static_size() -> bool {
32 true
33 }
34
35 fn signature() -> String {
36 String::from("()")
37 }
38}
39
40#[impl_for_tuples(1, 18)]
41impl Codec for Tuple {
42 fn has_static_size() -> bool {
43 for_tuples!(#( Tuple::has_static_size() )&*)
44 }
45
46 fn read(reader: &mut Reader) -> MayRevert<Self> {
47 if Self::has_static_size() {
48 let mut index = 0;
49 Ok(for_tuples!( ( #( {
50 let elem = reader.read::<Tuple>().in_tuple(index)?;
51 index +=1;
52 elem
53 } ),* ) ))
54 } else {
55 let reader = &mut reader.read_pointer()?;
56 let mut index = 0;
57 Ok(for_tuples!( ( #( {
58 let elem = reader.read::<Tuple>().in_tuple(index)?;
59 index +=1;
60 elem
61 } ),* ) ))
62 }
63 }
64
65 fn write(writer: &mut Writer, value: Self) {
66 if Self::has_static_size() {
67 for_tuples!( #( Tuple::write(writer, value.Tuple); )* );
68 } else {
69 let mut inner_writer = Writer::new();
70 for_tuples!( #( Tuple::write(&mut inner_writer, value.Tuple); )* );
71 writer.write_pointer(inner_writer.build());
72 }
73 }
74
75 fn signature() -> String {
76 let mut subtypes = Vec::new();
77 for_tuples!( #( subtypes.push(Tuple::signature()); )* );
78 alloc::format!("({})", subtypes.join(","))
79 }
80
81 fn is_explicit_tuple() -> bool {
82 true
83 }
84}
85
86impl Codec for H256 {
87 fn read(reader: &mut Reader) -> MayRevert<Self> {
88 let range = reader.move_cursor(32)?;
89
90 let data = reader
91 .input
92 .get(range)
93 .ok_or_else(|| RevertReason::read_out_of_bounds("bytes32"))?;
94
95 Ok(H256::from_slice(data))
96 }
97
98 fn write(writer: &mut Writer, value: Self) {
99 writer.data.extend_from_slice(value.as_bytes());
100 }
101
102 fn has_static_size() -> bool {
103 true
104 }
105
106 fn signature() -> String {
107 String::from("bytes32")
108 }
109}
110
111#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
115pub struct Address(pub H160);
116
117impl From<H160> for Address {
118 fn from(a: H160) -> Address {
119 Address(a)
120 }
121}
122
123impl From<Address> for H160 {
124 fn from(a: Address) -> H160 {
125 a.0
126 }
127}
128
129impl Address {
130 pub fn as_u64(&self) -> Option<u64> {
131 let _u64 = self.0.to_low_u64_be();
132 if self.0 == H160::from_low_u64_be(_u64) {
133 Some(_u64)
134 } else {
135 None
136 }
137 }
138}
139
140impl Codec for Address {
141 fn read(reader: &mut Reader) -> MayRevert<Self> {
142 let range = reader.move_cursor(32)?;
143
144 let data = reader
145 .input
146 .get(range)
147 .ok_or_else(|| RevertReason::read_out_of_bounds("address"))?;
148
149 Ok(H160::from_slice(&data[12..32]).into())
150 }
151
152 fn write(writer: &mut Writer, value: Self) {
153 H256::write(writer, value.0.into());
154 }
155
156 fn has_static_size() -> bool {
157 true
158 }
159
160 fn signature() -> String {
161 String::from("address")
162 }
163}
164
165impl Codec for U256 {
166 fn read(reader: &mut Reader) -> MayRevert<Self> {
167 let range = reader.move_cursor(32)?;
168
169 let data = reader
170 .input
171 .get(range)
172 .ok_or_else(|| RevertReason::read_out_of_bounds("uint256"))?;
173
174 Ok(U256::from_big_endian(data))
175 }
176
177 fn write(writer: &mut Writer, value: Self) {
178 writer.data.extend_from_slice(&value.to_big_endian());
179 }
180
181 fn has_static_size() -> bool {
182 true
183 }
184
185 fn signature() -> String {
186 String::from("uint256")
187 }
188}
189
190macro_rules! impl_evmdata_for_uints {
191 ($($uint:ty, )*) => {
192 $(
193 impl Codec for $uint {
194 fn read(reader: &mut Reader) -> MayRevert<Self> {
195 let value256: U256 = reader.read()
196 .map_err(|_| RevertReason::read_out_of_bounds(
197 Self::signature()
198 ))?;
199
200 value256
201 .try_into()
202 .map_err(|_| RevertReason::value_is_too_large(
203 Self::signature()
204 ).into())
205 }
206
207 fn write(writer: &mut Writer, value: Self) {
208 U256::write(writer, value.into());
209 }
210
211 fn has_static_size() -> bool {
212 true
213 }
214
215 fn signature() -> String {
216 alloc::format!("uint{}", core::mem::size_of::<Self>() * 8)
217 }
218 }
219 )*
220 };
221}
222
223impl_evmdata_for_uints!(u8, u16, u32, u64, u128,);
224
225impl Codec for bool {
226 fn read(reader: &mut Reader) -> MayRevert<Self> {
227 let h256 = H256::read(reader).map_err(|_| RevertReason::read_out_of_bounds("bool"))?;
228
229 Ok(!h256.is_zero())
230 }
231
232 fn write(writer: &mut Writer, value: Self) {
233 let mut buffer = [0u8; 32];
234 if value {
235 buffer[31] = 1;
236 }
237
238 writer.data.extend_from_slice(&buffer);
239 }
240
241 fn has_static_size() -> bool {
242 true
243 }
244
245 fn signature() -> String {
246 String::from("bool")
247 }
248}
249
250type ConstU32Max = ConstU32<{ u32::MAX }>;
251
252impl<T: Codec> Codec for Vec<T> {
253 fn read(reader: &mut Reader) -> MayRevert<Self> {
254 BoundedVec::<T, ConstU32Max>::read(reader).map(|x| x.into())
255 }
256
257 fn write(writer: &mut Writer, value: Self) {
258 BoundedVec::<T, ConstU32Max>::write(
259 writer,
260 BoundedVec {
261 inner: value,
262 _phantom: PhantomData,
263 },
264 )
265 }
266
267 fn has_static_size() -> bool {
268 false
269 }
270
271 fn signature() -> String {
272 alloc::format!("{}[]", T::signature())
273 }
274}
275
276#[derive(Clone, Debug, Eq, PartialEq)]
278pub struct BoundedVec<T, S> {
279 inner: Vec<T>,
280 _phantom: PhantomData<S>,
281}
282
283impl<T: Codec, S: Get<u32>> Codec for BoundedVec<T, S> {
284 fn read(reader: &mut Reader) -> MayRevert<Self> {
285 let mut inner_reader = reader.read_pointer()?;
286
287 let array_size: usize = inner_reader
288 .read::<U256>()
289 .map_err(|_| RevertReason::read_out_of_bounds("length"))?
290 .try_into()
291 .map_err(|_| RevertReason::value_is_too_large("length"))?;
292
293 if array_size > S::get() as usize {
294 return Err(RevertReason::value_is_too_large("length").into());
295 }
296
297 let mut array = vec![];
298
299 let mut item_reader = Reader {
300 input: inner_reader
301 .input
302 .get(32..)
303 .ok_or_else(|| RevertReason::read_out_of_bounds("array content"))?,
304 cursor: 0,
305 };
306
307 for i in 0..array_size {
308 array.push(item_reader.read().in_array(i)?);
309 }
310
311 Ok(BoundedVec {
312 inner: array,
313 _phantom: PhantomData,
314 })
315 }
316
317 fn write(writer: &mut Writer, value: Self) {
318 let value: Vec<_> = value.into();
319 let mut inner_writer = Writer::new().write(U256::from(value.len()));
320
321 for inner in value {
322 let shift = inner_writer.data.len();
327 let item_writer = Writer::new().write(inner);
328
329 inner_writer = inner_writer.write_raw_bytes(&item_writer.data);
330 for mut offset_datum in item_writer.offset_data {
331 offset_datum.offset_shift += 32;
332 offset_datum.offset_position += shift;
333 inner_writer.offset_data.push(offset_datum);
334 }
335 }
336
337 writer.write_pointer(inner_writer.build());
338 }
339
340 fn has_static_size() -> bool {
341 false
342 }
343
344 fn signature() -> String {
345 alloc::format!("{}[]", T::signature())
346 }
347}
348
349impl<T, S> From<Vec<T>> for BoundedVec<T, S> {
350 fn from(value: Vec<T>) -> Self {
351 BoundedVec {
352 inner: value,
353 _phantom: PhantomData,
354 }
355 }
356}
357
358impl<T: Clone, S> From<&[T]> for BoundedVec<T, S> {
359 fn from(value: &[T]) -> Self {
360 BoundedVec {
361 inner: value.to_vec(),
362 _phantom: PhantomData,
363 }
364 }
365}
366
367impl<T: Clone, S, const N: usize> From<[T; N]> for BoundedVec<T, S> {
368 fn from(value: [T; N]) -> Self {
369 BoundedVec {
370 inner: value.to_vec(),
371 _phantom: PhantomData,
372 }
373 }
374}
375
376impl<T, S> From<BoundedVec<T, S>> for Vec<T> {
377 fn from(value: BoundedVec<T, S>) -> Self {
378 value.inner
379 }
380}
381
382impl<T, S> Default for BoundedVec<T, S> {
383 fn default() -> Self {
384 Self {
385 inner: Default::default(),
386 _phantom: PhantomData,
387 }
388 }
389}
390
391impl<T, S> BoundedVec<T, S> {
392 pub fn len(&self) -> usize {
393 self.inner.len()
394 }
395
396 pub fn is_empty(&self) -> bool {
397 self.inner.is_empty()
398 }
399}