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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
use crate::errors::{ErrorKind, Result};
use eosio_client_keys::hash::hash_sha256;
use std::fs;

const WASM_COOKIE: [u8; 8] = [0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00];

pub struct WASM {
    pub code: Vec<u8>,
}
impl WASM {
    const HEXMAP: [char; 16] = [
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
    ];
    pub fn _read_hex_string(_in_str: String) -> Result<WASM> {
        Err("TBD".into())
    }
    pub fn read_file(filename: &str) -> Result<WASM> {
        let file = fs::read(filename)?;
        let slice = &file[0..WASM_COOKIE.len()].to_vec();
        let matching = slice
            .iter()
            .zip(WASM_COOKIE.iter())
            .filter(|&(a, b)| a == b)
            .count();

        if matching == WASM_COOKIE.len() {
            Ok(WASM { code: file })
        } else {
            Err(ErrorKind::InvalidWASMFormat.into())
        }
    }
    pub fn hash(&self) -> Vec<u8> {
        hash_sha256(&self.code)
    }
    pub fn to_hex(&self) -> String {
        let mut s: String = String::new();
        for byt in &self.code {
            s.push(WASM::HEXMAP[(byt >> 4) as usize]);
            s.push(WASM::HEXMAP[(byt & 0xf) as usize]);
        }
        s
    }
    pub fn dummy() -> Vec<u8> {
        //WASM_COOKIE.to_vec()
        Vec::new()
    }
}

#[cfg(test)]
mod test {
    use super::*;
    #[test]
    fn read_wasm() -> Result<()> {
        WASM::read_file("test/good.wasm")?;
        Ok(())
    }
}