icon_sdk/utils/
serializer.rs

1use serde_json::Value;
2use sha3::{Digest, Sha3_256};
3use std::collections::BTreeMap;
4use hex::encode;
5
6pub struct Serializer;
7
8impl Serializer {
9    pub fn serialize_transaction(data: &Value, hashed: bool) -> String {
10        let result_str = Self::value_traverse(data);
11        let result_string_replaced = &result_str[1..result_str.len() - 1];
12        let result = format!("icx_sendTransaction.{}", result_string_replaced);
13
14        if hashed {
15            format!("{}", encode(Sha3_256::digest(result.as_bytes())))
16        } else {
17            result
18        }
19    }
20
21    fn value_traverse(value: &Value) -> String {
22        match value {
23            Value::Object(obj) => {
24                let mut result = "{".to_string();
25                let sorted: BTreeMap<_, _> = obj.iter().collect();
26                for (key, val) in sorted {
27                    result.push_str(&format!("{}.", key));
28                    result.push_str(&Self::value_traverse(val));
29                    result.push('.');
30                }
31                if result.ends_with('.') {
32                    result.pop();
33                }
34                result.push('}');
35                result
36            },
37            Value::Array(arr) => {
38                let mut result = "[".to_string();
39                for val in arr {
40                    result.push_str(&Self::value_traverse(val));
41                    result.push('.');
42                }
43                if result.ends_with('.') {
44                    result.pop();
45                }
46                result.push(']');
47                result
48            },
49            Value::String(s) => Self::escape_string(s),
50            Value::Number(n) => n.to_string(),
51            Value::Bool(b) => b.to_string(),
52            Value::Null => "\\0".to_string(),
53        }
54    }
55
56    fn escape_string(value: &str) -> String {
57        value.replace("\\", "\\\\")
58            .replace(".", "\\.")
59            .replace("{", "\\{")
60            .replace("}", "\\}")
61            .replace("[", "\\[")
62            .replace("]", "\\]")
63    }
64}