1use sha3::{Digest, Keccak256};
10
11#[cfg(not(feature = "std"))]
12use crate::no_std_prelude::*;
13use crate::{
14 param_type::{ParamType, Writer},
15 Hash,
16};
17
18pub fn short_signature(name: &str, params: &[ParamType]) -> [u8; 4] {
20 let mut result = [0u8; 4];
21 fill_signature(name, params, &mut result);
22 result
23}
24
25pub fn long_signature(name: &str, params: &[ParamType]) -> Hash {
27 let mut result = [0u8; 32];
28 fill_signature(name, params, &mut result);
29 result.into()
30}
31
32fn fill_signature(name: &str, params: &[ParamType], result: &mut [u8]) {
33 let types = params.iter().map(Writer::write).collect::<Vec<String>>().join(",");
34
35 let data: Vec<u8> = From::from(format!("{name}({types})").as_str());
36
37 result.copy_from_slice(&Keccak256::digest(data)[..result.len()])
38}
39
40#[cfg(test)]
41mod tests {
42 use super::short_signature;
43 use crate::ParamType;
44 use hex_literal::hex;
45
46 #[test]
47 fn test_signature() {
48 assert_eq!(hex!("cdcd77c0"), short_signature("baz", &[ParamType::Uint(32), ParamType::Bool]));
49 }
50}