Line data Source code
1 : import 'dart:typed_data';
2 : import 'package:walletkit_dart/src/crypto/evm/entities/contract/contract_function_encoding.dart';
3 : import 'package:walletkit_dart/src/crypto/evm/entities/contract/contract_function_param.dart';
4 : import 'package:walletkit_dart/src/crypto/evm/entities/contract/parameter_type/function_parameter_type.dart';
5 : import 'dart:math';
6 :
7 7 : List<FunctionParamWithValue> decodeDataField({
8 : required Uint8List data,
9 : required List<FunctionParam> params,
10 : }) {
11 7 : final decodedParams = <FunctionParamWithValue>[];
12 : int offset = 0;
13 : int max_offset = 0;
14 14 : for (final param in params) {
15 7 : final decoded = decodeParameter(
16 : data: data,
17 7 : type: param.type,
18 : offset: offset,
19 : max_offset: max_offset,
20 : );
21 :
22 : offset = decoded.offset;
23 7 : max_offset = max(max_offset, decoded.max_offset);
24 :
25 7 : final decodedParam = FunctionParamWithValue.fromParam(param, decoded.value);
26 :
27 7 : decodedParams.add(decodedParam);
28 : }
29 :
30 7 : max_offset = max(max_offset, offset);
31 :
32 14 : if (max_offset != data.length) {
33 0 : throw Exception("offset is not equal to data length");
34 : }
35 :
36 : return decodedParams;
37 : }
38 :
39 7 : ({dynamic value, int offset, int max_offset}) decodeParameter({
40 : required Uint8List data,
41 : required FunctionParamType type,
42 : required int offset,
43 : required int max_offset,
44 : int header_offset_increment = 0,
45 : }) {
46 14 : final data_field = data.sublist(offset, offset + size_unit);
47 : final value = switch (type) {
48 14 : BaseFunctionParamType type => () {
49 7 : offset += size_unit;
50 7 : return type.decode(data_field);
51 7 : }.call(),
52 7 : TupleFunctionParamType type => () {
53 1 : if (type.isDynamic) {
54 4 : final headerOffset = FunctionParamInt().decode(data_field).toInt() +
55 : header_offset_increment;
56 1 : final (value, off) = type.decode(headerOffset, data);
57 1 : max_offset = max(max_offset, off);
58 1 : offset += size_unit;
59 : return value;
60 : }
61 :
62 : /// Tuple is not dynamic
63 1 : final (value, off) = type.decode(offset, data);
64 : offset = off;
65 : return value;
66 1 : }.call(),
67 11 : ArrayFunctionParamType type => () {
68 5 : if (type.isDynamic) {
69 20 : final headerOffset = FunctionParamInt().decode(data_field).toInt() +
70 : header_offset_increment;
71 5 : final (value, off) = type.decode(headerOffset, data);
72 5 : max_offset = max(max_offset, off);
73 5 : offset += size_unit;
74 : return value;
75 : }
76 :
77 : /// Array is not dynamic
78 0 : final (value, off) = type.decode(offset, data);
79 : offset = off;
80 : return value;
81 5 : }.call(),
82 10 : DynamicFunctionParamType type => () {
83 20 : final headerOffset = FunctionParamInt().decode(data_field).toInt() +
84 : header_offset_increment;
85 5 : final (value, off) = type.decode(headerOffset, data);
86 5 : max_offset = max(max_offset, off);
87 5 : offset += size_unit;
88 : return value;
89 5 : }.call(),
90 : };
91 :
92 7 : max_offset = max(max_offset, offset);
93 :
94 : return (
95 : value: value,
96 : offset: offset,
97 : max_offset: max_offset,
98 : );
99 : }
|