api3_common/abi/
encode.rs1use crate::abi::types::{Token, Word};
4use crate::Bytes;
5
6pub fn pad_u32(value: u32) -> Word {
8 let mut padded = [0u8; 32];
9 padded[28..32].copy_from_slice(&value.to_be_bytes());
10 padded
11}
12
13fn pad_bytes(bytes: &[u8]) -> Vec<Word> {
14 let mut result = vec![pad_u32(bytes.len() as u32)];
15 result.extend(pad_fixed_bytes(bytes));
16 result
17}
18
19fn pad_fixed_bytes(bytes: &[u8]) -> Vec<Word> {
20 let len = (bytes.len() + 31) / 32;
21 let mut result = Vec::with_capacity(len);
22 for i in 0..len {
23 let mut padded = [0u8; 32];
24
25 let to_copy = match i == len - 1 {
26 false => 32,
27 true => match bytes.len() % 32 {
28 0 => 32,
29 x => x,
30 },
31 };
32
33 let offset = 32 * i;
34 padded[..to_copy].copy_from_slice(&bytes[offset..offset + to_copy]);
35 result.push(padded);
36 }
37
38 result
39}
40
41#[derive(Debug)]
42enum Mediate {
43 Raw(Vec<Word>),
44 Prefixed(Vec<Word>),
45}
46
47impl Mediate {
48 fn head_len(&self) -> u32 {
49 match *self {
50 Mediate::Raw(ref raw) => 32 * raw.len() as u32,
51 Mediate::Prefixed(_) => 32,
52 }
53 }
54
55 fn tail_len(&self) -> u32 {
56 match *self {
57 Mediate::Raw(_) => 0,
58 Mediate::Prefixed(ref pre) => pre.len() as u32 * 32,
59 }
60 }
61
62 fn head(&self, suffix_offset: u32) -> Vec<Word> {
63 match *self {
64 Mediate::Raw(ref raw) => raw.clone(),
65 Mediate::Prefixed(_) => vec![pad_u32(suffix_offset)],
66 }
67 }
68
69 fn tail(&self) -> Vec<Word> {
70 match *self {
71 Mediate::Raw(_) => vec![],
72 Mediate::Prefixed(ref raw) => raw.clone(),
73 }
74 }
75}
76
77fn encode_head_tail(mediates: &[Mediate]) -> Vec<Word> {
78 let heads_len = mediates.iter().fold(0, |acc, m| acc + m.head_len());
79
80 let (mut result, len) = mediates.iter().fold(
81 (Vec::with_capacity(heads_len as usize), heads_len),
82 |(mut acc, offset), m| {
83 acc.extend(m.head(offset));
84 (acc, offset + m.tail_len())
85 },
86 );
87
88 let tails = mediates.iter().fold(
89 Vec::with_capacity((len - heads_len) as usize),
90 |mut acc, m| {
91 acc.extend(m.tail());
92 acc
93 },
94 );
95
96 result.extend(tails);
97 result
98}
99
100pub fn encode(tokens: &[Token]) -> Bytes {
102 let mediates = &tokens.iter().map(encode_token).collect::<Vec<_>>();
103
104 encode_head_tail(mediates)
105 .iter()
106 .flat_map(|word| word.to_vec())
107 .collect()
108}
109
110fn encode_token(token: &Token) -> Mediate {
111 match token {
112 Token::Address(ref address) => {
113 let mut padded = [0u8; 32];
114 padded[12..].copy_from_slice(address);
115 Mediate::Raw(vec![padded])
116 }
117 Token::Bytes(ref bytes) => Mediate::Prefixed(pad_bytes(bytes)),
118 Token::String(ref s) => Mediate::Prefixed(pad_bytes(s.as_bytes())),
119 Token::FixedBytes(ref bytes) => Mediate::Raw(pad_fixed_bytes(bytes)),
120 Token::Uint(uint) => Mediate::Raw(vec![(*uint).into()]),
121 Token::Int(int) => Mediate::Raw(vec![(*int).into()]),
122 }
123}
124
125#[cfg(test)]
126mod tests {
127 use crate::abi::encode::{encode, pad_u32};
128 use crate::abi::Token;
129 use hex_literal::hex;
130
131 #[test]
132 fn encode_address() {
133 let address = Token::Address([0x11u8; 20].into());
134 let encoded = encode(&[address]);
135 let expected = hex!("0000000000000000000000001111111111111111111111111111111111111111");
136 assert_eq!(encoded, expected);
137 }
138
139 #[test]
140 fn encode_two_addresses() {
141 let address1 = Token::Address([0x11u8; 20].into());
142 let address2 = Token::Address([0x22u8; 20].into());
143 let encoded = encode(&[address1, address2]);
144 let expected = hex!(
145 "
146 0000000000000000000000001111111111111111111111111111111111111111
147 0000000000000000000000002222222222222222222222222222222222222222
148 "
149 )
150 .to_vec();
151 assert_eq!(encoded, expected);
152 }
153
154 #[test]
155 fn encode_bytes() {
156 let bytes = Token::Bytes(vec![0x12, 0x34]);
157 let encoded = encode(&[bytes]);
158 let expected = hex!(
159 "
160 0000000000000000000000000000000000000000000000000000000000000020
161 0000000000000000000000000000000000000000000000000000000000000002
162 1234000000000000000000000000000000000000000000000000000000000000
163 "
164 )
165 .to_vec();
166 assert_eq!(encoded, expected);
167 }
168
169 #[test]
170 fn encode_fixed_bytes() {
171 let bytes = Token::FixedBytes(vec![0x12, 0x34]);
172 let encoded = encode(&[bytes]);
173 let expected = hex!("1234000000000000000000000000000000000000000000000000000000000000");
174 assert_eq!(encoded, expected);
175 }
176
177 #[test]
178 fn encode_string() {
179 let s = Token::String("gavofyork".to_owned());
180 let encoded = encode(&[s]);
181 let expected = hex!(
182 "
183 0000000000000000000000000000000000000000000000000000000000000020
184 0000000000000000000000000000000000000000000000000000000000000009
185 6761766f66796f726b0000000000000000000000000000000000000000000000
186 "
187 )
188 .to_vec();
189 assert_eq!(encoded, expected);
190 }
191
192 #[test]
193 fn encode_bytes2() {
194 let bytes = Token::Bytes(
195 hex!("10000000000000000000000000000000000000000000000000000000000002").to_vec(),
196 );
197 let encoded = encode(&[bytes]);
198 let expected = hex!(
199 "
200 0000000000000000000000000000000000000000000000000000000000000020
201 000000000000000000000000000000000000000000000000000000000000001f
202 1000000000000000000000000000000000000000000000000000000000000200
203 "
204 )
205 .to_vec();
206 assert_eq!(encoded, expected);
207 }
208
209 #[test]
210 fn encode_bytes3() {
211 let bytes = Token::Bytes(
212 hex!(
213 "
214 1000000000000000000000000000000000000000000000000000000000000000
215 1000000000000000000000000000000000000000000000000000000000000000
216 "
217 )
218 .to_vec(),
219 );
220 let encoded = encode(&[bytes]);
221 let expected = hex!(
222 "
223 0000000000000000000000000000000000000000000000000000000000000020
224 0000000000000000000000000000000000000000000000000000000000000040
225 1000000000000000000000000000000000000000000000000000000000000000
226 1000000000000000000000000000000000000000000000000000000000000000
227 "
228 )
229 .to_vec();
230 assert_eq!(encoded, expected);
231 }
232
233 #[test]
234 fn encode_two_bytes() {
235 let bytes1 = Token::Bytes(
236 hex!("10000000000000000000000000000000000000000000000000000000000002").to_vec(),
237 );
238 let bytes2 = Token::Bytes(
239 hex!("0010000000000000000000000000000000000000000000000000000000000002").to_vec(),
240 );
241 let encoded = encode(&[bytes1, bytes2]);
242 let expected = hex!(
243 "
244 0000000000000000000000000000000000000000000000000000000000000040
245 0000000000000000000000000000000000000000000000000000000000000080
246 000000000000000000000000000000000000000000000000000000000000001f
247 1000000000000000000000000000000000000000000000000000000000000200
248 0000000000000000000000000000000000000000000000000000000000000020
249 0010000000000000000000000000000000000000000000000000000000000002
250 "
251 )
252 .to_vec();
253 assert_eq!(encoded, expected);
254 }
255
256 #[test]
257 fn encode_uint() {
258 let mut uint = [0u8; 32];
259 uint[31] = 4;
260 let encoded = encode(&[Token::Uint(uint.into())]);
261 let expected = hex!("0000000000000000000000000000000000000000000000000000000000000004");
262 assert_eq!(encoded, expected);
263 }
264
265 #[test]
266 fn test_pad_u32() {
267 assert_eq!(pad_u32(0x1)[31], 1);
269 assert_eq!(pad_u32(0x100)[30], 1);
270 }
271}