1use signature::short_signature;
4use {Param, Token, Result, ErrorKind, Bytes, decode, ParamType, encode};
5
6#[derive(Debug, Clone, PartialEq, Deserialize)]
8pub struct Function {
9 pub name: String,
11 pub inputs: Vec<Param>,
13 pub outputs: Vec<Param>,
15 #[serde(default)]
17 pub constant: bool,
18}
19
20impl Function {
21 fn input_param_types(&self) -> Vec<ParamType> {
23 self.inputs.iter()
24 .map(|p| p.kind.clone())
25 .collect()
26 }
27
28 fn output_param_types(&self) -> Vec<ParamType> {
30 self.outputs.iter()
31 .map(|p| p.kind.clone())
32 .collect()
33 }
34
35 pub fn encode_input(&self, tokens: &[Token]) -> Result<Bytes> {
37 let params = self.input_param_types();
38
39 if !Token::types_check(tokens, ¶ms) {
40 return Err(ErrorKind::InvalidData.into());
41 }
42
43 let signed = short_signature(&self.name, ¶ms).to_vec();
44 let encoded = encode(tokens);
45 Ok(signed.into_iter().chain(encoded.into_iter()).collect())
46 }
47
48 pub fn decode_output(&self, data: &[u8]) -> Result<Vec<Token>> {
50 decode(&self.output_param_types(), &data)
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use {Token, Param, Function, ParamType};
57
58 #[test]
59 fn test_function_encode_call() {
60 let interface = Function {
61 name: "baz".to_owned(),
62 inputs: vec![Param {
63 name: "a".to_owned(),
64 kind: ParamType::Uint(32),
65 }, Param {
66 name: "b".to_owned(),
67 kind: ParamType::Bool,
68 }],
69 outputs: vec![],
70 constant: false,
71 };
72
73 let func = Function::from(interface);
74 let mut uint = [0u8; 32];
75 uint[31] = 69;
76 let encoded = func.encode_input(&[Token::Uint(uint.into()), Token::Bool(true)]).unwrap();
77 let expected = hex!("cdcd77c000000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000001").to_vec();
78 assert_eq!(encoded, expected);
79 }
80}