1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//! Zink ABI utils
#![cfg(feature = "selector")]

use crate::Abi;
use tiny_keccak::{Hasher, Sha3};

/// Generate a keccak hash of the input (sha3)
pub fn keccak256(input: &[u8]) -> [u8; 32] {
    let mut hasher = Sha3::v256();
    let mut output = [0; 32];
    hasher.update(input);
    hasher.finalize(&mut output);
    output
}

/// Parse selector from bytes.
pub fn parse(bytes: &[u8]) -> [u8; 4] {
    let mut selector = [0u8; 4];
    selector.copy_from_slice(&keccak256(bytes)[..4]);
    selector
}

impl Abi {
    /// Get function signature.
    pub fn signature(&self) -> String {
        self.name.clone()
            + "("
            + &self
                .inputs
                .iter()
                .map(|i| i.ty.as_ref())
                .collect::<Vec<_>>()
                .join(",")
            + ")"
    }

    /// Get function selector.
    pub fn selector(&self) -> [u8; 4] {
        parse(self.signature().as_bytes())
    }
}