casper_executor_wasm_common/
chain_utils.rs1use blake2::{digest::consts::U32, Blake2b, Digest};
2
3pub 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#[must_use]
34pub fn compute_next_contract_hash_version(
35 smart_contract_addr: [u8; 32],
36 next_version: u32,
37) -> [u8; 32] {
38 let mut hasher = Blake2b::<U32>::new();
39
40 hasher.update(smart_contract_addr);
41 hasher.update(next_version.to_le_bytes());
42
43 hasher.finalize().into()
44}
45
46#[cfg(test)]
47mod tests {
48 const SEED: [u8; 32] = [1u8; 32];
49
50 #[test]
51 fn test_compute_predictable_address() {
52 let initiator = [1u8; 32];
53 let bytecode_hash = [2u8; 32];
54
55 let predictable_address_1 =
56 super::compute_predictable_address("testnet", initiator, bytecode_hash, Some(SEED));
57 let predictable_address_2 =
58 super::compute_predictable_address("mainnet", initiator, bytecode_hash, Some(SEED));
59 assert_ne!(predictable_address_1, predictable_address_2);
60 }
61
62 #[test]
63 fn test_compute_nth_version_hash() {
64 let smart_contract_addr = [1u8; 32];
65 let mut next_version = 1;
66
67 let hash_1 = super::compute_next_contract_hash_version(smart_contract_addr, next_version);
68 next_version += 1;
69
70 let hash_2 = super::compute_next_contract_hash_version(smart_contract_addr, next_version);
71 assert_ne!(hash_1, hash_2);
72 }
73}