1use std::{collections::HashMap, str::FromStr};
4
5use crate::primitives::{Address, Bytes, Hex, H256, U256};
6use regex::Regex;
7use serde::{ser, Serialize, Serializer};
8use sha3::{Digest, Keccak256};
9
10use super::TypeDefinition;
11
12#[derive(Debug, thiserror::Error)]
13pub enum EncodeDataError {
14 #[error("{0}")]
15 Unknown(String),
16
17 #[error("Unsupport type for eip712, {0}")]
18 UnsupportType(String),
19
20 #[error("Type definition not found, {0}")]
21 TypeDefinitionNotFound(String),
22
23 #[error("Close tuple before calling start_tuple function")]
24 EndTuple,
25 #[error("Call start_tuple first, eip712 root type must be a structure")]
26 StartTuple,
27 #[error("start_tuple and end_tuple must be called in pairs")]
28 UnclosedTuple,
29 #[error("Encode data is empty")]
30 Empty,
31
32 #[error("Bytes32OutofRange: {0}")]
33 Bytes32OutofRange(String),
34
35 #[error("IntOutofRange: {0}")]
36 IntOutofRange(String),
37}
38
39impl ser::Error for EncodeDataError {
40 fn custom<T>(msg: T) -> Self
41 where
42 T: std::fmt::Display,
43 {
44 Self::Unknown(msg.to_string())
45 }
46}
47
48#[derive(Debug, Default)]
49struct TupleEncoder {
50 names: Vec<String>,
51 fields: Vec<[u8; 32]>,
52}
53
54impl TupleEncoder {
55 fn append_element(&mut self, data: [u8; 32]) {
56 self.fields.push(data);
57 }
58
59 fn last_name(&self) -> Option<&String> {
60 self.names.last()
61 }
62
63 fn append_element_name(&mut self, name: &str) {
64 log::debug!("append element {} index {}", name, self.names.len());
65 self.names.push(name.to_owned());
66 }
67
68 fn finalize(self, type_hash: [u8; 32], definition: TypeDefinition) -> [u8; 32] {
69 let mut hasher = Keccak256::new();
70
71 hasher.update(&type_hash);
72
73 for field in definition {
74 let index = self
75 .names
76 .iter()
77 .enumerate()
78 .find(|(_, n)| n.as_str() == field.name)
79 .map(|(index, _)| index)
80 .unwrap();
81
82 log::debug!(
83 "hash update element {} with index {}: {}",
84 field.name,
85 index,
86 Hex(&self.fields[index])
87 );
88
89 hasher.update(&self.fields[index])
90 }
91
92 hasher.finalize().into()
93 }
94}
95
96#[derive(Debug)]
97pub struct EIP712StructHasher<'a> {
98 hashed: Option<[u8; 32]>,
99 tuple_stack: Vec<TupleEncoder>,
100 types: &'a HashMap<String, TypeDefinition>,
101 primary_type: &'a str,
102 type_stack: Vec<(String, TypeDefinition)>,
103}
104
105fn extract_type_name(name: &str) -> String {
106 let regex = Regex::new(r#"^([^\[]+)\[\d*\]$"#).unwrap();
107
108 if let Some(caps) = regex.captures(name) {
109 caps[1].to_owned()
110 } else {
111 name.to_owned()
112 }
113}
114
115impl<'a> EIP712StructHasher<'a> {
116 pub fn finalize(mut self) -> Result<[u8; 32], EncodeDataError> {
118 if !self.tuple_stack.is_empty() {
119 return Err(EncodeDataError::UnclosedTuple);
120 }
121
122 if let Some(hashed) = self.hashed.take() {
123 Ok(hashed)
124 } else {
125 return Err(EncodeDataError::Empty);
126 }
127 }
128
129 fn start_encode_type(&mut self, name: &str) -> Result<(), EncodeDataError> {
130 self.append_element_name(name)?;
131
132 if self.type_stack.is_empty() {
133 if let Some(definition) = self.types.get(self.primary_type) {
134 self.type_stack
135 .push((self.primary_type.to_owned(), definition.to_owned()));
136 } else {
137 return Err(EncodeDataError::TypeDefinitionNotFound(
138 self.primary_type.to_owned(),
139 ));
140 }
141 }
142
143 let parent_type = self.type_stack.last().unwrap();
144
145 if let Some(type_definition) = parent_type.1.iter().find(|d| d.name == name) {
146 log::debug!("start encode type {}", type_definition.r#type);
147
148 let type_name = extract_type_name(&type_definition.r#type);
149
150 if let Some(definition) = self.types.get(&type_name) {
151 self.type_stack.push((type_name, definition.to_owned()));
152
153 return Ok(());
154 } else {
155 log::debug!("process builtin type {}", type_name);
157 return Ok(());
158 }
159 } else {
160 log::debug!("maybe none field {}", name);
161 return Ok(());
162 }
164 }
165
166 fn type_hash(&mut self) -> Result<[u8; 32], EncodeDataError> {
173 if self.type_stack.is_empty() {
174 if let Some(definition) = self.types.get(self.primary_type) {
175 self.type_stack
176 .push((self.primary_type.to_owned(), definition.to_owned()));
177 } else {
178 return Err(EncodeDataError::TypeDefinitionNotFound(
179 self.primary_type.to_owned(),
180 ));
181 }
182 }
183
184 let primary_type = self.type_stack.last().unwrap();
185
186 let mut types = HashMap::<String, (String, TypeDefinition)>::new();
187
188 let mut stack = vec![primary_type];
189
190 while !stack.is_empty() {
191 let current = stack.pop().unwrap();
192 for field in ¤t.1 {
193 let type_name = extract_type_name(&field.r#type);
194
195 if !types.contains_key(&type_name) {
196 if let Some(definition) = self.types.get(&type_name) {
197 types.insert(type_name.clone(), (type_name, definition.to_owned()));
198 }
199 }
200 }
201 }
202
203 let mut keys = types.keys().collect::<Vec<_>>();
204
205 keys.sort_by(|a, b| a.cmp(b));
206
207 let mut sorted = vec![primary_type];
208
209 for key in keys {
210 let value = types.get(key.as_str());
211 sorted.push(value.unwrap());
212 }
213
214 let encode_type = sorted
215 .iter()
216 .map(|(name, fields)| {
217 let fields = fields
218 .iter()
219 .map(|f| format!("{} {}", f.r#type, f.name))
220 .collect::<Vec<_>>();
221 format!("{}({})", name, fields.join(","))
222 })
223 .collect::<Vec<_>>()
224 .join("");
225
226 log::debug!("encode type {}", encode_type);
227
228 Ok(Keccak256::new()
229 .chain_update(encode_type.as_bytes())
230 .finalize()
231 .into())
232 }
233
234 pub fn start_tuple(&mut self) -> Result<(), EncodeDataError> {
236 self.tuple_stack.push(TupleEncoder {
237 ..Default::default()
238 });
239
240 Ok(())
241 }
242
243 pub fn end_tuple(&mut self) -> Result<(), EncodeDataError> {
244 if let Some(tuple) = self.tuple_stack.pop() {
245 let encode_data = tuple.finalize(self.type_hash()?, self.type_stack.pop().unwrap().1);
246
247 if let Some(tuple) = self.tuple_stack.last_mut() {
248 tuple.append_element(encode_data);
249 } else {
250 self.hashed = Some(encode_data);
251 }
252
253 Ok(())
254 } else {
255 Err(EncodeDataError::EndTuple)
256 }
257 }
258
259 pub fn append_element(&mut self, data: [u8; 32]) -> Result<(), EncodeDataError> {
260 if let Some(tuple) = self.tuple_stack.last_mut() {
261 tuple.append_element(data);
262 Ok(())
263 } else {
264 Err(EncodeDataError::EndTuple)
265 }
266 }
267
268 fn append_element_name(&mut self, name: &str) -> Result<(), EncodeDataError> {
269 if let Some(tuple) = self.tuple_stack.last_mut() {
270 tuple.append_element_name(name);
271 Ok(())
272 } else {
273 Err(EncodeDataError::EndTuple)
274 }
275 }
276
277 fn element_type_name(&self) -> Result<Option<String>, EncodeDataError> {
278 if let Some(tuple) = self.tuple_stack.last() {
279 if let Some(name) = tuple.last_name() {
280 let (_, fields) = self.type_stack.last().unwrap();
281
282 if let Some(field) = fields.iter().find(|f| f.name.as_str() == name) {
283 return Ok(Some(field.r#type.clone()));
284 }
285 }
286
287 Ok(None)
288 } else {
289 Err(EncodeDataError::EndTuple)
290 }
291 }
292}
293
294impl<'a, 'b> Serializer for &'a mut EIP712StructHasher<'b> {
295 type Ok = ();
296 type Error = EncodeDataError;
297 type SerializeSeq = Self;
298 type SerializeTuple = Self;
299 type SerializeTupleStruct = Self;
300 type SerializeTupleVariant = Self;
301 type SerializeMap = Self;
302 type SerializeStruct = Self;
303 type SerializeStructVariant = Self;
304
305 fn is_human_readable(&self) -> bool {
306 false
307 }
308 fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> {
309 unimplemented!()
310 }
311
312 fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
313 self.append_element(Keccak256::new().chain_update(v).finalize().into())
314 }
315
316 fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> {
317 unimplemented!("Contract abi don't support rust char")
318 }
319
320 fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
321 unimplemented!("EIP712 don't support f32")
322 }
323
324 fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
325 unimplemented!("EIP712 don't support f64")
326 }
327
328 fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
329 let mut buff = if v.is_negative() {
330 [0u8; 32]
331 } else {
332 [0xffu8; 32]
333 };
334
335 buff[16..].copy_from_slice(&v.to_be_bytes());
336
337 self.append_element(buff)
338 }
339
340 fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> {
341 self.serialize_i128(_v as i128)
342 }
343
344 fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> {
345 self.serialize_i128(_v as i128)
346 }
347
348 fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> {
349 self.serialize_i128(_v as i128)
350 }
351
352 fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> {
353 self.serialize_i128(_v as i128)
354 }
355
356 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
357 self.start_tuple()?;
358
359 Ok(self)
360 }
361
362 fn serialize_newtype_struct<T: ?Sized>(
363 self,
364 name: &'static str,
365 value: &T,
366 ) -> Result<Self::Ok, Self::Error>
367 where
368 T: serde::Serialize,
369 {
370 match name {
371 "bytes" | "bytesN" => {
372 let bytes = unsafe { (value as *const T).cast::<Vec<u8>>().as_ref().unwrap() };
373
374 return self.append_element(Keccak256::new().chain_update(bytes).finalize().into());
375 }
376 "address" => {
377 let bytes = unsafe { (value as *const T).cast::<Vec<u8>>().as_ref().unwrap() };
378
379 let mut buf = [0u8; 32];
380
381 buf[12..].copy_from_slice(bytes.as_ref());
382
383 return self.append_element(buf);
384 }
385 "uint256" | "int256" => {
386 let bytes = unsafe { (value as *const T).cast::<Vec<u8>>().as_ref().unwrap() };
387
388 let mut buf = [0u8; 32];
389
390 buf[(32 - bytes.len())..].copy_from_slice(bytes.as_ref());
391
392 return self.append_element(buf);
393 }
394 _ => {
395 return Err(EncodeDataError::UnsupportType(name.to_owned()));
396 }
397 }
398 }
399
400 fn serialize_newtype_variant<T: ?Sized>(
401 self,
402 name: &'static str,
403 _variant_index: u32,
404 variant: &'static str,
405 _value: &T,
406 ) -> Result<Self::Ok, Self::Error>
407 where
408 T: serde::Serialize,
409 {
410 return Err(EncodeDataError::UnsupportType(format!(
411 "enum {}::{}",
412 name, variant
413 )));
414 }
415
416 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
417 Ok(())
418 }
419
420 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
421 unimplemented!("EIP712 don't support rust enum")
422 }
423
424 fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
425 where
426 T: serde::Serialize,
427 {
428 value.serialize(self)
429 }
430
431 fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
432 if let Some(type_name) = self.element_type_name()? {
433 log::debug!("serialize_str {}, type_name {}", v, type_name);
434 match type_name.as_str() {
435 "bytes" | "bytesN" => {
436 let bytes = Bytes::from_str(v).map_err(ser::Error::custom)?;
437
438 return self
439 .append_element(Keccak256::new().chain_update(bytes).finalize().into());
440 }
441 "address" => {
442 let address = Address::try_from(v).map_err(ser::Error::custom)?;
443
444 let mut bytes = [0u8; 32];
445
446 bytes[12..].copy_from_slice(address.as_ref());
447
448 return self.append_element(bytes);
449 }
450 "uint256" => {
451 let value = if v.starts_with("0x") {
452 U256::from_str_radix(&v[2..], 16).map_err(ser::Error::custom)?
453 } else {
454 U256::from_str_radix(v, 10).map_err(ser::Error::custom)?
455 };
456
457 let buf = value.to_be_bytes();
458
459 return self.append_element(buf);
460 }
461 _ => {}
462 }
463 }
464
465 self.append_element(
466 Keccak256::new()
467 .chain_update(v.as_bytes())
468 .finalize()
469 .into(),
470 )
471 }
472
473 fn serialize_struct(
474 self,
475 _name: &'static str,
476 _len: usize,
477 ) -> Result<Self::SerializeStruct, Self::Error> {
478 self.start_tuple()?;
479
480 Ok(self)
481 }
482
483 fn serialize_struct_variant(
484 self,
485 _name: &'static str,
486 _variant_index: u32,
487 _variant: &'static str,
488 _len: usize,
489 ) -> Result<Self::SerializeStructVariant, Self::Error> {
490 unimplemented!("EIP712 don't support rust enum")
491 }
492
493 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
494 unimplemented!("EIP712 don't support serialize tuple")
495 }
496
497 fn serialize_tuple_struct(
498 self,
499 _name: &'static str,
500 _len: usize,
501 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
502 unimplemented!("EIP712 don't support serialize tuple_struct")
503 }
504
505 fn serialize_tuple_variant(
506 self,
507 _name: &'static str,
508 _variant_index: u32,
509 _variant: &'static str,
510 _len: usize,
511 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
512 unimplemented!("Contract abi don't support rust enum")
513 }
514
515 fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
516 let mut buff = [0u8; 32];
517
518 buff[16..].copy_from_slice(&v.to_be_bytes());
519
520 self.append_element(buff)
521 }
522
523 fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> {
524 self.serialize_u128(_v as u128)
525 }
526
527 fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> {
528 self.serialize_u128(_v as u128)
529 }
530
531 fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> {
532 self.serialize_u128(_v as u128)
533 }
534
535 fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> {
536 self.serialize_u128(_v as u128)
537 }
538
539 fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
540 Ok(())
541 }
542
543 fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok, Self::Error> {
544 Ok(())
545 }
546
547 fn serialize_unit_variant(
548 self,
549 _name: &'static str,
550 _variant_index: u32,
551 _variant: &'static str,
552 ) -> Result<Self::Ok, Self::Error> {
553 unimplemented!("Contract abi don't support rust enum")
554 }
555}
556
557impl<'a, 'b> ser::SerializeStruct for &'a mut EIP712StructHasher<'b> {
558 type Error = EncodeDataError;
559
560 type Ok = ();
561 fn end(self) -> Result<Self::Ok, Self::Error> {
562 self.end_tuple()
563 }
564
565 fn serialize_field<T: ?Sized>(
566 &mut self,
567 key: &'static str,
568 value: &T,
569 ) -> Result<(), Self::Error>
570 where
571 T: serde::Serialize,
572 {
573 self.start_encode_type(key)?;
574 value.serialize(&mut **self)
575 }
576}
577
578impl<'a, 'b> ser::SerializeMap for &'a mut EIP712StructHasher<'b> {
579 type Error = EncodeDataError;
580
581 type Ok = ();
582 fn end(self) -> Result<Self::Ok, Self::Error> {
583 self.end_tuple()
584 }
585
586 fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error>
587 where
588 T: serde::Serialize,
589 {
590 let name = serde_json::to_string(key).map_err(ser::Error::custom)?;
591
592 let reg = Regex::new(r#"^"[^"]*"$"#).unwrap();
593
594 if !reg.is_match(&name) {
595 return Err(EncodeDataError::Unknown(
596 "HashStruct only support map with string key".to_owned(),
597 ));
598 }
599
600 self.start_encode_type(&name.as_str()[1..(name.len() - 1)])
601 }
602
603 fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
604 where
605 T: serde::Serialize,
606 {
607 value.serialize(&mut **self)
608 }
609}
610
611impl<'a, 'b> ser::SerializeSeq for &'a mut EIP712StructHasher<'b> {
612 type Error = EncodeDataError;
613
614 type Ok = ();
615 fn end(self) -> Result<Self::Ok, Self::Error> {
616 unimplemented!()
617 }
618
619 fn serialize_element<T: ?Sized>(&mut self, _value: &T) -> Result<(), Self::Error>
620 where
621 T: serde::Serialize,
622 {
623 unimplemented!()
624 }
625}
626
627impl<'a, 'b> ser::SerializeStructVariant for &'a mut EIP712StructHasher<'b> {
628 type Error = EncodeDataError;
629
630 type Ok = ();
631 fn end(self) -> Result<Self::Ok, Self::Error> {
632 unimplemented!()
633 }
634
635 fn serialize_field<T: ?Sized>(
636 &mut self,
637 _key: &'static str,
638 _value: &T,
639 ) -> Result<(), Self::Error>
640 where
641 T: serde::Serialize,
642 {
643 unimplemented!()
644 }
645}
646
647impl<'a, 'b> ser::SerializeTuple for &'a mut EIP712StructHasher<'b> {
648 type Error = EncodeDataError;
649
650 type Ok = ();
651 fn end(self) -> Result<Self::Ok, Self::Error> {
652 unimplemented!()
653 }
654
655 fn serialize_element<T: ?Sized>(&mut self, _value: &T) -> Result<(), Self::Error>
656 where
657 T: serde::Serialize,
658 {
659 unimplemented!()
660 }
661}
662
663impl<'a, 'b> ser::SerializeTupleVariant for &'a mut EIP712StructHasher<'b> {
664 type Error = EncodeDataError;
665
666 type Ok = ();
667 fn end(self) -> Result<Self::Ok, Self::Error> {
668 unimplemented!()
669 }
670
671 fn serialize_field<T: ?Sized>(&mut self, _value: &T) -> Result<(), Self::Error>
672 where
673 T: serde::Serialize,
674 {
675 unimplemented!()
676 }
677}
678
679impl<'a, 'b> ser::SerializeTupleStruct for &'a mut EIP712StructHasher<'b> {
680 type Error = EncodeDataError;
681
682 type Ok = ();
683 fn end(self) -> Result<Self::Ok, Self::Error> {
684 unimplemented!()
685 }
686
687 fn serialize_field<T: ?Sized>(&mut self, _value: &T) -> Result<(), Self::Error>
688 where
689 T: serde::Serialize,
690 {
691 unimplemented!()
692 }
693}
694
695pub fn eip712_hash_struct<S: Serialize>(
698 primary_type: &str,
699 types: &HashMap<String, TypeDefinition>,
700 value: &S,
701) -> Result<H256, EncodeDataError> {
702 let mut hasher = EIP712StructHasher {
703 type_stack: vec![],
704 types,
705 hashed: None,
706 tuple_stack: vec![],
707 primary_type,
708 };
709
710 value.serialize(&mut hasher)?;
711
712 Ok(hasher.finalize()?.into())
713}