casper_executor_wasm_common/
chain_utils.rs

1use blake2::{digest::consts::U32, Blake2b, Digest};
2
3/// Compute a predictable address for a contract.
4///
5/// The address is computed as the hash of the chain name, initiator account, and the hash of the
6/// Wasm code.
7pub fn compute_predictable_address<T: AsRef<[u8]>>(
8    chain_name: T,
9    initiator_address: [u8; 32],
10    bytecode_hash: [u8; 32],
11    seed: Option<[u8; 32]>,
12) -> [u8; 32] {
13    let mut hasher = Blake2b::<U32>::new();
14
15    hasher.update(chain_name);
16    hasher.update(initiator_address);
17    hasher.update(bytecode_hash);
18
19    if let Some(seed) = seed {
20        hasher.update(seed);
21    }
22
23    hasher.finalize().into()
24}
25
26pub fn compute_wasm_bytecode_hash<T: AsRef<[u8]>>(wasm_bytes: T) -> [u8; 32] {
27    let mut hasher = Blake2b::<U32>::new();
28    hasher.update(wasm_bytes);
29    let hash = hasher.finalize();
30    hash.into()
31}
32
33#[cfg(test)]
34mod tests {
35    const SEED: [u8; 32] = [1u8; 32];
36
37    #[test]
38    fn test_compute_predictable_address() {
39        let initiator = [1u8; 32];
40        let bytecode_hash = [2u8; 32];
41
42        let predictable_address_1 =
43            super::compute_predictable_address("testnet", initiator, bytecode_hash, Some(SEED));
44        let predictable_address_2 =
45            super::compute_predictable_address("mainnet", initiator, bytecode_hash, Some(SEED));
46        assert_ne!(predictable_address_1, predictable_address_2);
47    }
48}