1use std::cmp::max;
2use std::str::FromStr;
3
4use num_bigint::{
5 BigInt,
6 BigUint,
7 Sign,
8};
9
10use self::private::Sealed;
11use crate::contract::contract_function_selector::ContractFunctionSelector;
12use crate::ethereum::SolidityAddress;
13
14#[derive(Debug, Clone, Default)]
16pub struct ContractFunctionParameters {
17 args: Vec<Argument>,
18}
19
20#[derive(Debug, Clone)]
21struct Argument {
22 type_name: &'static str,
23 value_bytes: Vec<u8>,
24 is_dynamic: bool,
25}
26
27mod private {
28 pub trait Sealed {}
29 impl Sealed for String {}
30 impl Sealed for str {}
31 impl Sealed for [u8; 32] {}
32}
33
34pub trait AsBytes32: Sealed {
35 fn as_bytes32(&self) -> &[u8];
36}
37
38impl<T: Sealed + AsRef<[u8]> + ?Sized> AsBytes32 for T {
39 fn as_bytes32(&self) -> &[u8] {
40 self.as_ref()
41 }
42}
43
44trait IntEncode {
45 fn get_is_negative_and_be_bytes(&self) -> (bool, Vec<u8>);
46}
47
48impl IntEncode for u8 {
49 fn get_is_negative_and_be_bytes(&self) -> (bool, Vec<u8>) {
50 (false, self.to_be_bytes().to_vec())
51 }
52}
53
54impl IntEncode for i8 {
55 fn get_is_negative_and_be_bytes(&self) -> (bool, Vec<u8>) {
56 (self.is_negative(), self.to_be_bytes().to_vec())
57 }
58}
59
60impl IntEncode for u16 {
61 fn get_is_negative_and_be_bytes(&self) -> (bool, Vec<u8>) {
62 (false, self.to_be_bytes().to_vec())
63 }
64}
65
66impl IntEncode for i16 {
67 fn get_is_negative_and_be_bytes(&self) -> (bool, Vec<u8>) {
68 (self.is_negative(), self.to_be_bytes().to_vec())
69 }
70}
71
72impl IntEncode for u32 {
73 fn get_is_negative_and_be_bytes(&self) -> (bool, Vec<u8>) {
74 (false, self.to_be_bytes().to_vec())
75 }
76}
77
78impl IntEncode for i32 {
79 fn get_is_negative_and_be_bytes(&self) -> (bool, Vec<u8>) {
80 (self.is_negative(), self.to_be_bytes().to_vec())
81 }
82}
83
84impl IntEncode for u64 {
85 fn get_is_negative_and_be_bytes(&self) -> (bool, Vec<u8>) {
86 (false, self.to_be_bytes().to_vec())
87 }
88}
89
90impl IntEncode for i64 {
91 fn get_is_negative_and_be_bytes(&self) -> (bool, Vec<u8>) {
92 (self.is_negative(), self.to_be_bytes().to_vec())
93 }
94}
95
96impl IntEncode for u128 {
97 fn get_is_negative_and_be_bytes(&self) -> (bool, Vec<u8>) {
98 (false, self.to_be_bytes().to_vec())
99 }
100}
101
102impl IntEncode for i128 {
103 fn get_is_negative_and_be_bytes(&self) -> (bool, Vec<u8>) {
104 (self.is_negative(), self.to_be_bytes().to_vec())
105 }
106}
107
108impl IntEncode for BigUint {
109 fn get_is_negative_and_be_bytes(&self) -> (bool, Vec<u8>) {
110 (false, self.to_bytes_be())
111 }
112}
113
114impl IntEncode for BigInt {
115 fn get_is_negative_and_be_bytes(&self) -> (bool, Vec<u8>) {
116 (self.sign() == Sign::Minus, self.to_signed_bytes_be())
117 }
118}
119
120#[allow(clippy::needless_pass_by_value)]
122impl ContractFunctionParameters {
123 #[must_use]
125 pub fn new() -> Self {
126 Self::default()
127 }
128
129 pub fn to_bytes(&self, func_name: Option<&str>) -> Vec<u8> {
136 let mut current_dynamic_offset = self.args.len() * 32;
137 let mut arg_bytes = Vec::new();
138 let mut dynamic_arg_bytes = Vec::new();
139 let mut function_selector = func_name.map(ContractFunctionSelector::new);
140 for arg in &self.args {
141 if let Some(selector) = &mut function_selector {
142 selector.add_param_type(arg.type_name);
143 }
144 if arg.is_dynamic {
145 arg_bytes.extend_from_slice(
146 left_pad_32_bytes(current_dynamic_offset.to_be_bytes().as_slice(), false)
147 .as_slice(),
148 );
149 dynamic_arg_bytes.extend_from_slice(arg.value_bytes.as_slice());
150 current_dynamic_offset += arg.value_bytes.len();
151 } else {
152 arg_bytes.extend_from_slice(arg.value_bytes.as_slice());
153 }
154 }
155
156 arg_bytes.append(&mut dynamic_arg_bytes);
157
158 if let Some(selector) = &mut function_selector {
159 let mut out_bytes = Vec::from(selector.finish());
160 out_bytes.append(&mut arg_bytes);
161 out_bytes
162 } else {
163 arg_bytes
164 }
165 }
166
167 pub fn add_string<T: AsRef<str>>(&mut self, val: T) -> &mut Self {
169 self.args.push(Argument {
170 type_name: "string",
171 value_bytes: encode_dynamic_bytes(val.as_ref().as_bytes()),
172 is_dynamic: true,
173 });
174 self
175 }
176
177 pub fn add_string_array<T: AsRef<str>>(&mut self, val: &[T]) -> &mut Self {
179 self.args.push(Argument {
180 type_name: "string[]",
181 value_bytes: encode_array_of_dynamic_byte_arrays(
182 val.iter().map(|s| s.as_ref().as_bytes()),
183 val.len(),
184 ),
185 is_dynamic: true,
186 });
187 self
188 }
189
190 pub fn add_bytes(&mut self, val: &[u8]) -> &mut Self {
192 self.args.push(Argument {
193 type_name: "bytes",
194 value_bytes: encode_dynamic_bytes(val),
195 is_dynamic: true,
196 });
197 self
198 }
199
200 pub fn add_bytes_array(&mut self, val: &[&[u8]]) -> &mut Self {
202 self.args.push(Argument {
203 type_name: "bytes[]",
204 value_bytes: encode_array_of_dynamic_byte_arrays(val, val.len()),
205 is_dynamic: true,
206 });
207 self
208 }
209
210 pub fn add_bytes32<T: AsBytes32 + ?Sized>(&mut self, val: &T) -> &mut Self {
212 self.args.push(Argument {
213 type_name: "bytes32",
214 value_bytes: encode_array_of_32_byte(val),
215 is_dynamic: false,
216 });
217 self
218 }
219
220 pub fn add_bytes32_array(&mut self, val: &[[u8; 32]]) -> &mut Self {
222 self.args.push(Argument {
223 type_name: "bytes32",
224 value_bytes: encode_array_of_32_byte_elements(val.iter().copied(), val.len()),
225 is_dynamic: true,
226 });
227 self
228 }
229
230 pub fn add_bool(&mut self, val: bool) -> &mut Self {
232 self.args.push(Argument {
233 type_name: "bool",
234 value_bytes: left_pad_32_bytes(
235 u32::from(val).to_be_bytes().as_slice(),
237 false,
238 )
239 .to_vec(),
240 is_dynamic: false,
241 });
242 self
243 }
244
245 fn add_int<T>(&mut self, val: &T, type_name: &'static str, byte_count: isize) -> &mut Self
246 where
247 T: IntEncode,
248 {
249 self.args.push(Argument {
250 type_name,
251 value_bytes: truncate_and_left_pad_32_bytes(val, byte_count).to_vec(),
252 is_dynamic: false,
253 });
254 self
255 }
256
257 fn add_int_array<T>(
258 &mut self,
259 values: &[T],
260 type_name: &'static str,
261 byte_count: isize,
262 ) -> &mut Self
263 where
264 T: IntEncode,
265 {
266 self.args.push(Argument {
267 type_name,
268 value_bytes: encode_array_of_32_byte_elements(
269 values.iter().map(|val| truncate_and_left_pad_32_bytes(val, byte_count)),
270 values.len(),
271 ),
272 is_dynamic: true,
273 });
274 self
275 }
276
277 pub fn add_int8(&mut self, val: i8) -> &mut Self {
279 self.add_int(&val, "int8", 1)
280 }
281
282 pub fn add_int16(&mut self, val: i16) -> &mut Self {
284 self.add_int(&val, "int16", 2)
285 }
286
287 pub fn add_int24(&mut self, val: i32) -> &mut Self {
289 self.add_int(&val, "int24", 3)
290 }
291
292 pub fn add_int32(&mut self, val: i32) -> &mut Self {
294 self.add_int(&val, "int32", 4)
295 }
296
297 pub fn add_int40(&mut self, val: i64) -> &mut Self {
299 self.add_int(&val, "int40", 5)
300 }
301
302 pub fn add_int48(&mut self, val: i64) -> &mut Self {
304 self.add_int(&val, "int48", 6)
305 }
306
307 pub fn add_int56(&mut self, val: i64) -> &mut Self {
309 self.add_int(&val, "int56", 7)
310 }
311
312 pub fn add_int64(&mut self, val: i64) -> &mut Self {
314 self.add_int(&val, "int64", 8)
315 }
316
317 pub fn add_int72(&mut self, val: i128) -> &mut Self {
319 self.add_int(&val, "int72", 9)
320 }
321
322 pub fn add_int80(&mut self, val: i128) -> &mut Self {
324 self.add_int(&val, "int80", 10)
325 }
326
327 pub fn add_int88(&mut self, val: i128) -> &mut Self {
329 self.add_int(&val, "int88", 11)
330 }
331
332 pub fn add_int96(&mut self, val: i128) -> &mut Self {
334 self.add_int(&val, "int96", 12)
335 }
336
337 pub fn add_int104(&mut self, val: i128) -> &mut Self {
339 self.add_int(&val, "int104", 13)
340 }
341
342 pub fn add_int112(&mut self, val: i128) -> &mut Self {
344 self.add_int(&val, "int112", 14)
345 }
346
347 pub fn add_int120(&mut self, val: i128) -> &mut Self {
349 self.add_int(&val, "int120", 15)
350 }
351
352 pub fn add_int128(&mut self, val: i128) -> &mut Self {
354 self.add_int(&val, "int128", 16)
355 }
356
357 pub fn add_int136(&mut self, val: BigInt) -> &mut Self {
359 self.add_int(&val, "int136", 17)
360 }
361
362 pub fn add_int144(&mut self, val: BigInt) -> &mut Self {
364 self.add_int(&val, "int144", 18)
365 }
366
367 pub fn add_int152(&mut self, val: BigInt) -> &mut Self {
369 self.add_int(&val, "int152", 19)
370 }
371
372 pub fn add_int160(&mut self, val: BigInt) -> &mut Self {
374 self.add_int(&val, "int160", 20)
375 }
376
377 pub fn add_int168(&mut self, val: BigInt) -> &mut Self {
379 self.add_int(&val, "int168", 21)
380 }
381
382 pub fn add_int176(&mut self, val: BigInt) -> &mut Self {
384 self.add_int(&val, "int176", 22)
385 }
386
387 pub fn add_int184(&mut self, val: BigInt) -> &mut Self {
389 self.add_int(&val, "int184", 23)
390 }
391
392 pub fn add_int192(&mut self, val: BigInt) -> &mut Self {
394 self.add_int(&val, "int192", 24)
395 }
396
397 pub fn add_int200(&mut self, val: BigInt) -> &mut Self {
399 self.add_int(&val, "int200", 25)
400 }
401
402 pub fn add_int208(&mut self, val: BigInt) -> &mut Self {
404 self.add_int(&val, "int208", 26)
405 }
406
407 pub fn add_int216(&mut self, val: BigInt) -> &mut Self {
409 self.add_int(&val, "int216", 27)
410 }
411
412 pub fn add_int224(&mut self, val: BigInt) -> &mut Self {
414 self.add_int(&val, "int224", 28)
415 }
416
417 pub fn add_int232(&mut self, val: BigInt) -> &mut Self {
419 self.add_int(&val, "int232", 29)
420 }
421
422 pub fn add_int240(&mut self, val: BigInt) -> &mut Self {
424 self.add_int(&val, "int240", 30)
425 }
426
427 pub fn add_int248(&mut self, val: BigInt) -> &mut Self {
429 self.add_int(&val, "int248", 31)
430 }
431
432 pub fn add_int256(&mut self, val: BigInt) -> &mut Self {
434 self.add_int(&val, "int256", 32)
435 }
436
437 pub fn add_int8_array(&mut self, values: &[i8]) -> &mut Self {
439 self.add_int_array(values, "int8[]", 1)
440 }
441
442 pub fn add_int16_array(&mut self, values: &[i16]) -> &mut Self {
444 self.add_int_array(values, "int16[]", 2)
445 }
446
447 pub fn add_int24_array(&mut self, values: &[i32]) -> &mut Self {
449 self.add_int_array(values, "int24[]", 3)
450 }
451
452 pub fn add_int32_array(&mut self, values: &[i32]) -> &mut Self {
454 self.add_int_array(values, "int32[]", 4)
455 }
456
457 pub fn add_int40_array(&mut self, values: &[i64]) -> &mut Self {
459 self.add_int_array(values, "int40[]", 5)
460 }
461
462 pub fn add_int48_array(&mut self, values: &[i64]) -> &mut Self {
464 self.add_int_array(values, "int48[]", 6)
465 }
466
467 pub fn add_int56_array(&mut self, values: &[i64]) -> &mut Self {
469 self.add_int_array(values, "int56[]", 7)
470 }
471
472 pub fn add_int64_array(&mut self, values: &[i64]) -> &mut Self {
474 self.add_int_array(values, "int64[]", 8)
475 }
476
477 pub fn add_int72_array(&mut self, values: &[i128]) -> &mut Self {
479 self.add_int_array(values, "int72[]", 9)
480 }
481
482 pub fn add_int80_array(&mut self, values: &[i128]) -> &mut Self {
484 self.add_int_array(values, "int80[]", 10)
485 }
486
487 pub fn add_int88_array(&mut self, values: &[i128]) -> &mut Self {
489 self.add_int_array(values, "int88[]", 11)
490 }
491
492 pub fn add_int96_array(&mut self, values: &[i128]) -> &mut Self {
494 self.add_int_array(values, "int96[]", 12)
495 }
496
497 pub fn add_int104_array(&mut self, values: &[i128]) -> &mut Self {
499 self.add_int_array(values, "int104[]", 13)
500 }
501
502 pub fn add_int112_array(&mut self, values: &[i128]) -> &mut Self {
504 self.add_int_array(values, "int112[]", 14)
505 }
506
507 pub fn add_int120_array(&mut self, values: &[i128]) -> &mut Self {
509 self.add_int_array(values, "int120[]", 15)
510 }
511
512 pub fn add_int128_array(&mut self, values: &[i128]) -> &mut Self {
514 self.add_int_array(values, "int128[]", 16)
515 }
516
517 pub fn add_int136_array(&mut self, values: &[BigInt]) -> &mut Self {
519 self.add_int_array(values, "int136[]", 17)
520 }
521
522 pub fn add_int144_array(&mut self, values: &[BigInt]) -> &mut Self {
524 self.add_int_array(values, "int144[]", 18)
525 }
526
527 pub fn add_int152_array(&mut self, values: &[BigInt]) -> &mut Self {
529 self.add_int_array(values, "int152[]", 19)
530 }
531
532 pub fn add_int160_array(&mut self, values: &[BigInt]) -> &mut Self {
534 self.add_int_array(values, "int160[]", 20)
535 }
536
537 pub fn add_int168_array(&mut self, values: &[BigInt]) -> &mut Self {
539 self.add_int_array(values, "int168[]", 21)
540 }
541
542 pub fn add_int176_array(&mut self, values: &[BigInt]) -> &mut Self {
544 self.add_int_array(values, "int176[]", 22)
545 }
546
547 pub fn add_int184_array(&mut self, values: &[BigInt]) -> &mut Self {
549 self.add_int_array(values, "int184[]", 23)
550 }
551
552 pub fn add_int192_array(&mut self, values: &[BigInt]) -> &mut Self {
554 self.add_int_array(values, "int192[]", 24)
555 }
556
557 pub fn add_int200_array(&mut self, values: &[BigInt]) -> &mut Self {
559 self.add_int_array(values, "int200[]", 25)
560 }
561
562 pub fn add_int208_array(&mut self, values: &[BigInt]) -> &mut Self {
564 self.add_int_array(values, "int208[]", 26)
565 }
566
567 pub fn add_int216_array(&mut self, values: &[BigInt]) -> &mut Self {
569 self.add_int_array(values, "int216[]", 27)
570 }
571
572 pub fn add_int224_array(&mut self, values: &[BigInt]) -> &mut Self {
574 self.add_int_array(values, "int224[]", 28)
575 }
576
577 pub fn add_int232_array(&mut self, values: &[BigInt]) -> &mut Self {
579 self.add_int_array(values, "int232[]", 29)
580 }
581
582 pub fn add_int240_array(&mut self, values: &[BigInt]) -> &mut Self {
584 self.add_int_array(values, "int240[]", 30)
585 }
586
587 pub fn add_int248_array(&mut self, values: &[BigInt]) -> &mut Self {
589 self.add_int_array(values, "int248[]", 31)
590 }
591
592 pub fn add_int256_array(&mut self, values: &[BigInt]) -> &mut Self {
594 self.add_int_array(values, "int256[]", 32)
595 }
596
597 pub fn add_uint8(&mut self, val: u8) -> &mut Self {
599 self.add_int(&val, "uint8", 1)
600 }
601
602 pub fn add_uint16(&mut self, val: u16) -> &mut Self {
604 self.add_int(&val, "uint16", 2)
605 }
606
607 pub fn add_uint24(&mut self, val: u32) -> &mut Self {
609 self.add_int(&val, "uint24", 3)
610 }
611
612 pub fn add_uint32(&mut self, val: u32) -> &mut Self {
614 self.add_int(&val, "uint32", 4)
615 }
616
617 pub fn add_uint40(&mut self, val: u64) -> &mut Self {
619 self.add_int(&val, "uint40", 5)
620 }
621
622 pub fn add_uint48(&mut self, val: u64) -> &mut Self {
624 self.add_int(&val, "uint48", 6)
625 }
626
627 pub fn add_uint56(&mut self, val: u64) -> &mut Self {
629 self.add_int(&val, "uint56", 7)
630 }
631
632 pub fn add_uint64(&mut self, val: u64) -> &mut Self {
634 self.add_int(&val, "uint64", 8)
635 }
636
637 pub fn add_uint72(&mut self, val: u128) -> &mut Self {
639 self.add_int(&val, "uint72", 9)
640 }
641
642 pub fn add_uint80(&mut self, val: u128) -> &mut Self {
644 self.add_int(&val, "uint80", 10)
645 }
646
647 pub fn add_uint88(&mut self, val: u128) -> &mut Self {
649 self.add_int(&val, "uint88", 11)
650 }
651
652 pub fn add_uint96(&mut self, val: u128) -> &mut Self {
654 self.add_int(&val, "uint96", 12)
655 }
656
657 pub fn add_uint104(&mut self, val: u128) -> &mut Self {
659 self.add_int(&val, "uint104", 13)
660 }
661
662 pub fn add_uint112(&mut self, val: u128) -> &mut Self {
664 self.add_int(&val, "uint112", 14)
665 }
666
667 pub fn add_uint120(&mut self, val: u128) -> &mut Self {
669 self.add_int(&val, "uint120", 15)
670 }
671
672 pub fn add_uint128(&mut self, val: u128) -> &mut Self {
674 self.add_int(&val, "uint128", 16)
675 }
676
677 pub fn add_uint136(&mut self, val: BigUint) -> &mut Self {
679 self.add_int(&val, "uint136", 17)
680 }
681
682 pub fn add_uint144(&mut self, val: BigUint) -> &mut Self {
684 self.add_int(&val, "uint144", 18)
685 }
686
687 pub fn add_uint152(&mut self, val: BigUint) -> &mut Self {
689 self.add_int(&val, "uint152", 19)
690 }
691
692 pub fn add_uint160(&mut self, val: BigUint) -> &mut Self {
694 self.add_int(&val, "uint160", 20)
695 }
696
697 pub fn add_uint168(&mut self, val: BigUint) -> &mut Self {
699 self.add_int(&val, "uint168", 21)
700 }
701
702 pub fn add_uint176(&mut self, val: BigUint) -> &mut Self {
704 self.add_int(&val, "uint176", 22)
705 }
706
707 pub fn add_uint184(&mut self, val: BigUint) -> &mut Self {
709 self.add_int(&val, "uint184", 23)
710 }
711
712 pub fn add_uint192(&mut self, val: BigUint) -> &mut Self {
714 self.add_int(&val, "uint192", 24)
715 }
716
717 pub fn add_uint200(&mut self, val: BigUint) -> &mut Self {
719 self.add_int(&val, "uint200", 25)
720 }
721
722 pub fn add_uint208(&mut self, val: BigUint) -> &mut Self {
724 self.add_int(&val, "uint208", 26)
725 }
726
727 pub fn add_uint216(&mut self, val: BigUint) -> &mut Self {
729 self.add_int(&val, "uint216", 27)
730 }
731
732 pub fn add_uint224(&mut self, val: BigUint) -> &mut Self {
734 self.add_int(&val, "uint224", 28)
735 }
736
737 pub fn add_uint232(&mut self, val: BigUint) -> &mut Self {
739 self.add_int(&val, "uint232", 29)
740 }
741
742 pub fn add_uint240(&mut self, val: BigUint) -> &mut Self {
744 self.add_int(&val, "uint240", 30)
745 }
746
747 pub fn add_uint248(&mut self, val: BigUint) -> &mut Self {
749 self.add_int(&val, "uint248", 31)
750 }
751
752 pub fn add_uint256(&mut self, val: BigUint) -> &mut Self {
754 self.add_int(&val, "uint256", 32)
755 }
756
757 pub fn add_uint8_array(&mut self, values: &[u8]) -> &mut Self {
759 self.add_int_array(values, "uint8[]", 1)
760 }
761
762 pub fn add_uint16_array(&mut self, values: &[u16]) -> &mut Self {
764 self.add_int_array(values, "uint16[]", 2)
765 }
766
767 pub fn add_uint24_array(&mut self, values: &[u32]) -> &mut Self {
769 self.add_int_array(values, "uint24[]", 3)
770 }
771
772 pub fn add_uint32_array(&mut self, values: &[u32]) -> &mut Self {
774 self.add_int_array(values, "uint32[]", 4)
775 }
776
777 pub fn add_uint40_array(&mut self, values: &[u64]) -> &mut Self {
779 self.add_int_array(values, "uint40[]", 5)
780 }
781
782 pub fn add_uint48_array(&mut self, values: &[u64]) -> &mut Self {
784 self.add_int_array(values, "uint48[]", 6)
785 }
786
787 pub fn add_uint56_array(&mut self, values: &[u64]) -> &mut Self {
789 self.add_int_array(values, "uint56[]", 7)
790 }
791
792 pub fn add_uint64_array(&mut self, values: &[u64]) -> &mut Self {
794 self.add_int_array(values, "uint64[]", 8)
795 }
796
797 pub fn add_uint72_array(&mut self, values: &[u128]) -> &mut Self {
799 self.add_int_array(values, "uint72[]", 9)
800 }
801
802 pub fn add_uint80_array(&mut self, values: &[u128]) -> &mut Self {
804 self.add_int_array(values, "uint80[]", 10)
805 }
806
807 pub fn add_uint88_array(&mut self, values: &[u128]) -> &mut Self {
809 self.add_int_array(values, "uint88[]", 11)
810 }
811
812 pub fn add_uint96_array(&mut self, values: &[u128]) -> &mut Self {
814 self.add_int_array(values, "uint96[]", 12)
815 }
816
817 pub fn add_uint104_array(&mut self, values: &[u128]) -> &mut Self {
819 self.add_int_array(values, "uint104[]", 13)
820 }
821
822 pub fn add_uint112_array(&mut self, values: &[u128]) -> &mut Self {
824 self.add_int_array(values, "uint112[]", 14)
825 }
826
827 pub fn add_uint120_array(&mut self, values: &[u128]) -> &mut Self {
829 self.add_int_array(values, "uint120[]", 15)
830 }
831
832 pub fn add_uint128_array(&mut self, values: &[u128]) -> &mut Self {
834 self.add_int_array(values, "uint128[]", 16)
835 }
836
837 pub fn add_uint136_array(&mut self, values: &[BigUint]) -> &mut Self {
839 self.add_int_array(values, "uint136[]", 17)
840 }
841
842 pub fn add_uint144_array(&mut self, values: &[BigUint]) -> &mut Self {
844 self.add_int_array(values, "uint144[]", 18)
845 }
846
847 pub fn add_uint152_array(&mut self, values: &[BigUint]) -> &mut Self {
849 self.add_int_array(values, "uint152[]", 19)
850 }
851
852 pub fn add_uint160_array(&mut self, values: &[BigUint]) -> &mut Self {
854 self.add_int_array(values, "uint160[]", 20)
855 }
856
857 pub fn add_uint168_array(&mut self, values: &[BigUint]) -> &mut Self {
859 self.add_int_array(values, "uint168[]", 21)
860 }
861
862 pub fn add_uint176_array(&mut self, values: &[BigUint]) -> &mut Self {
864 self.add_int_array(values, "uint176[]", 22)
865 }
866
867 pub fn add_uint184_array(&mut self, values: &[BigUint]) -> &mut Self {
869 self.add_int_array(values, "uint184[]", 23)
870 }
871
872 pub fn add_uint192_array(&mut self, values: &[BigUint]) -> &mut Self {
874 self.add_int_array(values, "uint192[]", 24)
875 }
876
877 pub fn add_uint200_array(&mut self, values: &[BigUint]) -> &mut Self {
879 self.add_int_array(values, "uint200[]", 25)
880 }
881
882 pub fn add_uint208_array(&mut self, values: &[BigUint]) -> &mut Self {
884 self.add_int_array(values, "uint208[]", 26)
885 }
886
887 pub fn add_uint216_array(&mut self, values: &[BigUint]) -> &mut Self {
889 self.add_int_array(values, "uint216[]", 27)
890 }
891
892 pub fn add_uint224_array(&mut self, values: &[BigUint]) -> &mut Self {
894 self.add_int_array(values, "uint224[]", 28)
895 }
896
897 pub fn add_uint232_array(&mut self, values: &[BigUint]) -> &mut Self {
899 self.add_int_array(values, "uint232[]", 29)
900 }
901
902 pub fn add_uint240_array(&mut self, values: &[BigUint]) -> &mut Self {
904 self.add_int_array(values, "uint240[]", 30)
905 }
906
907 pub fn add_uint248_array(&mut self, values: &[BigUint]) -> &mut Self {
909 self.add_int_array(values, "uint248[]", 31)
910 }
911
912 pub fn add_uint256_array(&mut self, values: &[BigUint]) -> &mut Self {
914 self.add_int_array(values, "uint256[]", 32)
915 }
916
917 pub fn add_address(&mut self, address: &str) -> &mut Self {
919 self.args.push(Argument {
920 type_name: "address",
921 value_bytes: encode_address(address).to_vec(),
922 is_dynamic: false,
923 });
924 self
925 }
926
927 pub fn add_address_array(&mut self, addresses: &[&str]) -> &mut Self {
929 self.args.push(Argument {
930 type_name: "address[]",
931 value_bytes: encode_array_of_32_byte_elements(
932 addresses.iter().map(|addr| encode_address(addr)),
933 addresses.len(),
934 ),
935 is_dynamic: true,
936 });
937 self
938 }
939
940 pub fn add_function(
945 &mut self,
946 address: &str,
947 mut selector: ContractFunctionSelector,
948 ) -> &mut Self {
949 let mut value_bytes = SolidityAddress::from_str(address).unwrap().to_bytes().to_vec();
950 value_bytes.extend(selector.finish());
951 right_pad_32_bytes(&mut value_bytes);
952
953 self.args.push(Argument {
954 type_name: "function",
955 value_bytes: value_bytes,
956 is_dynamic: false,
957 });
958 self
959 }
960}
961
962fn left_pad_32_bytes(bytes: &[u8], is_negative: bool) -> [u8; 32] {
963 let pad_byte = if is_negative { 0xFF } else { 0x00 };
964
965 let mut result = [pad_byte; 32];
966 result[(32 - bytes.len())..].copy_from_slice(bytes);
967 result
968}
969
970fn truncate_and_left_pad_32_bytes<T>(val: &T, byte_count: isize) -> [u8; 32]
971where
972 T: IntEncode,
973{
974 let (is_negative, full_value_bytes) = val.get_is_negative_and_be_bytes();
975 let truncated_value_bytes =
976 &full_value_bytes[max((full_value_bytes.len() as isize) - byte_count, 0) as usize..];
977 left_pad_32_bytes(truncated_value_bytes, is_negative)
978}
979
980fn right_pad_32_bytes(buf: &mut Vec<u8>) {
982 let rem = buf.len() % 32;
983 if rem != 0 {
984 let padding = [0_u8; 32];
985 buf.extend_from_slice(&padding[..(32 - rem)])
986 }
987}
988
989fn encode_address(address: &str) -> [u8; 32] {
990 left_pad_32_bytes(SolidityAddress::from_str(address).unwrap().0 .0.as_slice(), false)
991}
992
993fn encode_dynamic_bytes(bytes: &[u8]) -> Vec<u8> {
994 let mut out_bytes = left_pad_32_bytes(bytes.len().to_be_bytes().as_slice(), false).to_vec();
995 out_bytes.extend(bytes);
996 right_pad_32_bytes(&mut out_bytes);
997 out_bytes
998}
999
1000fn encode_array_of_dynamic_byte_arrays<I>(elements: I, elements_len: usize) -> Vec<u8>
1001where
1002 I: IntoIterator,
1003 I::Item: AsRef<[u8]>,
1004{
1005 let head_len = (elements_len + 1) * 32;
1006 let mut out_bytes = Vec::with_capacity(head_len);
1007 out_bytes.extend_from_slice(
1008 left_pad_32_bytes(elements_len.to_be_bytes().as_slice(), false).as_slice(),
1009 );
1010 let mut current_offset = elements_len * 32;
1011 let mut body_bytes: Vec<u8> = Vec::new();
1012 for element in elements {
1013 let element = element.as_ref();
1014 out_bytes.extend_from_slice(
1015 left_pad_32_bytes(current_offset.to_be_bytes().as_slice(), false).as_slice(),
1016 );
1017 current_offset += element.len();
1018 body_bytes.extend(element);
1019 }
1020 out_bytes.extend(body_bytes);
1021 out_bytes
1022}
1023
1024fn encode_array_of_32_byte_elements<I>(elements: I, elements_len: usize) -> Vec<u8>
1025where
1026 I: IntoIterator<Item = [u8; 32]>,
1027{
1028 let mut out_bytes = left_pad_32_bytes(elements_len.to_be_bytes().as_slice(), false).to_vec();
1029 out_bytes.reserve(out_bytes.len() + (elements_len * 32));
1030 out_bytes.extend(elements.into_iter().flatten());
1031 out_bytes
1032}
1033
1034fn encode_array_of_32_byte<T: AsBytes32 + ?Sized>(elements: &T) -> Vec<u8> {
1035 let slice = elements.as_bytes32();
1036 if slice.len() > 32 {
1037 panic!("32 bytes exceeded in contract function call")
1038 }
1039
1040 let mut new_bytes = slice.to_vec();
1041 right_pad_32_bytes(&mut new_bytes);
1042 new_bytes
1043}
1044
1045#[cfg(test)]
1046mod tests {
1047 use num_bigint::{
1048 BigInt,
1049 BigUint,
1050 };
1051
1052 use crate::contract::contract_function_parameters::ContractFunctionParameters;
1053 use crate::contract::contract_function_selector::ContractFunctionSelector;
1054
1055 #[test]
1056 fn misc_params() {
1057 let param_bytes = ContractFunctionParameters::new()
1058 .add_uint8(0x1)
1059 .add_int8(-0x2)
1060 .add_uint32(0x3)
1061 .add_int32(-0x4)
1062 .add_uint64(0x4)
1063 .add_int64(-0x5)
1064 .add_uint256(BigUint::from(0x6_u32))
1065 .add_int256(BigInt::from(-0x7))
1066 .add_uint8_array([0x1, 0x2, 0x3, 0x4].as_slice())
1067 .add_int8_array([-0x5, 0x6, 0x7, -0x8].as_slice())
1068 .add_uint32_array([0x9, 0xA, 0xB, 0xC].as_slice())
1069 .add_int32_array([-0xD, 0xE, 0xF, -0x10].as_slice())
1070 .add_uint64_array([0x11, 0x12, 0x13, 0x14].as_slice())
1071 .add_int64_array([-0x15, 0x16, 0x17, -0x18].as_slice())
1072 .add_uint256_array([BigUint::from(0x19_u32)].as_slice())
1073 .add_int256_array([BigInt::from(-0x1A)].as_slice())
1074 .to_bytes(Some("foo"));
1075
1076 assert_eq!(
1077 hex::encode(param_bytes),
1078 "11bcd903\
1079 0000000000000000000000000000000000000000000000000000000000000001\
1080 fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\
1081 0000000000000000000000000000000000000000000000000000000000000003\
1082 fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc\
1083 0000000000000000000000000000000000000000000000000000000000000004\
1084 fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\
1085 0000000000000000000000000000000000000000000000000000000000000006\
1086 fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\
1087 0000000000000000000000000000000000000000000000000000000000000200\
1088 00000000000000000000000000000000000000000000000000000000000002a0\
1089 0000000000000000000000000000000000000000000000000000000000000340\
1090 00000000000000000000000000000000000000000000000000000000000003e0\
1091 0000000000000000000000000000000000000000000000000000000000000480\
1092 0000000000000000000000000000000000000000000000000000000000000520\
1093 00000000000000000000000000000000000000000000000000000000000005c0\
1094 0000000000000000000000000000000000000000000000000000000000000600\
1095 0000000000000000000000000000000000000000000000000000000000000004\
1096 0000000000000000000000000000000000000000000000000000000000000001\
1097 0000000000000000000000000000000000000000000000000000000000000002\
1098 0000000000000000000000000000000000000000000000000000000000000003\
1099 0000000000000000000000000000000000000000000000000000000000000004\
1100 0000000000000000000000000000000000000000000000000000000000000004\
1101 fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\
1102 0000000000000000000000000000000000000000000000000000000000000006\
1103 0000000000000000000000000000000000000000000000000000000000000007\
1104 fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8\
1105 0000000000000000000000000000000000000000000000000000000000000004\
1106 0000000000000000000000000000000000000000000000000000000000000009\
1107 000000000000000000000000000000000000000000000000000000000000000a\
1108 000000000000000000000000000000000000000000000000000000000000000b\
1109 000000000000000000000000000000000000000000000000000000000000000c\
1110 0000000000000000000000000000000000000000000000000000000000000004\
1111 fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3\
1112 000000000000000000000000000000000000000000000000000000000000000e\
1113 000000000000000000000000000000000000000000000000000000000000000f\
1114 fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0\
1115 0000000000000000000000000000000000000000000000000000000000000004\
1116 0000000000000000000000000000000000000000000000000000000000000011\
1117 0000000000000000000000000000000000000000000000000000000000000012\
1118 0000000000000000000000000000000000000000000000000000000000000013\
1119 0000000000000000000000000000000000000000000000000000000000000014\
1120 0000000000000000000000000000000000000000000000000000000000000004\
1121 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeb\
1122 0000000000000000000000000000000000000000000000000000000000000016\
1123 0000000000000000000000000000000000000000000000000000000000000017\
1124 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe8\
1125 0000000000000000000000000000000000000000000000000000000000000001\
1126 0000000000000000000000000000000000000000000000000000000000000019\
1127 0000000000000000000000000000000000000000000000000000000000000001\
1128 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6"
1129 )
1130 }
1131
1132 #[test]
1133 fn address_params() {
1134 let param_bytes = ContractFunctionParameters::new()
1135 .add_address("1122334455667788990011223344556677889900")
1136 .add_address("0x1122334455667788990011223344556677889900")
1137 .add_address_array(
1138 [
1139 "1122334455667788990011223344556677889900",
1140 "1122334455667788990011223344556677889900",
1141 ]
1142 .as_slice(),
1143 )
1144 .to_bytes(Some("foo"));
1145
1146 assert_eq!(
1147 hex::encode(param_bytes),
1148 "7d48c86d\
1149 0000000000000000000000001122334455667788990011223344556677889900\
1150 0000000000000000000000001122334455667788990011223344556677889900\
1151 0000000000000000000000000000000000000000000000000000000000000060\
1152 0000000000000000000000000000000000000000000000000000000000000002\
1153 0000000000000000000000001122334455667788990011223344556677889900\
1154 0000000000000000000000001122334455667788990011223344556677889900"
1155 )
1156 }
1157
1158 #[test]
1159 fn function_params() {
1160 let param_bytes = ContractFunctionParameters::new()
1161 .add_function(
1162 "1122334455667788990011223344556677889900",
1163 ContractFunctionSelector::from([1, 2, 3, 4]),
1164 )
1165 .add_function(
1166 "0x1122334455667788990011223344556677889900",
1167 ContractFunctionSelector::new("randomFunction").add_bool().clone(),
1168 )
1169 .to_bytes(Some("foo"));
1170
1171 assert_eq!(
1172 hex::encode(param_bytes),
1173 "c99c40cd\
1174 1122334455667788990011223344556677889900010203040000000000000000\
1175 112233445566778899001122334455667788990063441d820000000000000000"
1176 );
1177 }
1178
1179 #[test]
1181 fn long_string() {
1182 let s = "abcd".repeat(63);
1183
1184 let bytes = ContractFunctionParameters::new().add_string(s).to_bytes(None);
1185
1186 let mut buf = String::with_capacity(bytes.len() * 2 + ((bytes.len() * 2) / 64));
1188 for line in bytes.chunks(32).map(hex::encode) {
1189 if !buf.is_empty() {
1190 buf.push('\n');
1191 }
1192
1193 buf.push_str(&line);
1194 }
1195
1196 expect_test::expect![[r#"
1197 0000000000000000000000000000000000000000000000000000000000000020
1198 00000000000000000000000000000000000000000000000000000000000000fc
1199 6162636461626364616263646162636461626364616263646162636461626364
1200 6162636461626364616263646162636461626364616263646162636461626364
1201 6162636461626364616263646162636461626364616263646162636461626364
1202 6162636461626364616263646162636461626364616263646162636461626364
1203 6162636461626364616263646162636461626364616263646162636461626364
1204 6162636461626364616263646162636461626364616263646162636461626364
1205 6162636461626364616263646162636461626364616263646162636461626364
1206 6162636461626364616263646162636461626364616263646162636400000000"#]]
1207 .assert_eq(&buf);
1208 }
1209
1210 #[test]
1211 fn string_to_bytes32() {
1212 let s = "alice".to_string();
1213
1214 let bytes = ContractFunctionParameters::new().add_bytes32(&s).to_bytes(None);
1215
1216 let mut buf = String::with_capacity(bytes.len() * 2 + ((bytes.len() * 2) / 64));
1218 for line in bytes.chunks(32).map(hex::encode) {
1219 if !buf.is_empty() {
1220 buf.push('\n');
1221 }
1222
1223 buf.push_str(&line);
1224 }
1225
1226 expect_test::expect!["616c696365000000000000000000000000000000000000000000000000000000"]
1227 .assert_eq(&buf);
1228 }
1229
1230 #[test]
1231 fn str_to_bytes32() {
1232 let s = "alice";
1233
1234 let bytes = ContractFunctionParameters::new().add_bytes32(s).to_bytes(None);
1235
1236 let mut buf = String::with_capacity(bytes.len() * 2 + ((bytes.len() * 2) / 64));
1237 for line in bytes.chunks(32).map(hex::encode) {
1238 if !buf.is_empty() {
1239 buf.push('\n');
1240 }
1241
1242 buf.push_str(&line);
1243 }
1244
1245 expect_test::expect!["616c696365000000000000000000000000000000000000000000000000000000"]
1246 .assert_eq(&buf);
1247 }
1248
1249 #[test]
1250 fn bytes_to_bytes32() {
1251 let mut array = [0u8; 32];
1252
1253 let str_sample = "aliceandbob".as_bytes();
1254
1255 for (i, &byte) in str_sample.iter().enumerate() {
1256 array[i] = byte;
1257 }
1258
1259 let bytes = ContractFunctionParameters::new().add_bytes32(&array).to_bytes(None);
1260
1261 let mut buf = String::with_capacity(bytes.len() * 2 + ((bytes.len() * 2) / 64));
1262 for line in bytes.chunks(32).map(hex::encode) {
1263 if !buf.is_empty() {
1264 buf.push('\n');
1265 }
1266
1267 buf.push_str(&line);
1268 }
1269
1270 expect_test::expect!["616c696365616e64626f62000000000000000000000000000000000000000000"]
1271 .assert_eq(&buf);
1272 }
1273
1274 #[test]
1275 #[should_panic]
1276 fn bytes32_panic() {
1277 let str_sample = "alice bought some burgers from bob";
1278
1279 ContractFunctionParameters::new().add_bytes32(str_sample).to_bytes(None);
1281 }
1282}