ethcontract_common/
hash.rs1use tiny_keccak::{Hasher, Keccak};
4
5pub fn keccak256<B>(data: B) -> [u8; 32]
7where
8 B: AsRef<[u8]>,
9{
10 let mut output = [0u8; 32];
11 let mut hasher = Keccak::v256();
12 hasher.update(data.as_ref());
13 hasher.finalize(&mut output);
14 output
15}
16
17pub type H32 = [u8; 4];
22
23pub fn function_selector<S>(signature: S) -> H32
27where
28 S: AsRef<str>,
29{
30 let hash = keccak256(signature.as_ref());
31 let mut selector = H32::default();
32 selector.copy_from_slice(&hash[0..4]);
33 selector
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39
40 #[test]
41 fn simple_keccak_hash() {
42 assert_eq!(
45 &keccak256([0xea]),
46 b"\x2f\x20\x67\x74\x59\x12\x06\x77\x48\x4f\x71\x04\xc7\x6d\xeb\x68\
47 \x46\xa2\xc0\x71\xf9\xb3\x15\x2c\x10\x3b\xb1\x2c\xd5\x4d\x1a\x4a"
48 );
49 }
50
51 #[test]
52 fn simple_function_signature() {
53 assert_eq!(
56 function_selector("myMethod(uint256,string)"),
57 [0x24, 0xee, 0x00, 0x97],
58 );
59 }
60
61 #[test]
62 fn revert_function_signature() {
63 assert_eq!(function_selector("Error(string)"), [0x08, 0xc3, 0x79, 0xa0]);
64 }
65}