Skip to main content

yevm_core/
misc.rs

1use yevm_base::{Acc, Int};
2use yevm_misc::keccak256;
3
4pub fn is_precompile(addr: &Acc) -> bool {
5    let id = addr.as_u64();
6    addr.as_ref()[..12].iter().all(|&b| b == 0) && ((1u64..=0xa).contains(&id) || id == 0x100)
7}
8
9/// CREATE address: keccak256(rlp([sender, nonce]))[12:]
10pub fn create_address(sender: &Acc, nonce: u64) -> Acc {
11    // RLP([addr, nonce]): list of [20-byte addr, nonce]
12    let mut payload = Vec::with_capacity(23);
13    payload.push(0x94); // string length 20
14    payload.extend_from_slice(sender.as_ref());
15    if nonce == 0 {
16        payload.push(0x80); // RLP encoding of 0
17    } else if nonce < 128 {
18        payload.push(nonce as u8);
19    } else {
20        let n = nonce.to_be_bytes();
21        let start = n.iter().position(|&b| b != 0).unwrap_or(7);
22        payload.push(0x80 + (8 - start) as u8);
23        payload.extend_from_slice(&n[start..]);
24    }
25    let mut buf = Vec::with_capacity(payload.len() + 1);
26    if payload.len() < 56 {
27        buf.push(0xc0 + payload.len() as u8);
28    } else {
29        buf.push(0xf7 + 1); // length of length
30        buf.push(payload.len() as u8);
31    }
32    buf.extend(payload);
33    let hash = keccak256(&buf);
34    Acc::from(&hash.as_ref()[12..])
35}
36
37/// CREATE2 address: keccak256(0xff ++ sender ++ salt ++ keccak256(init_code))[12:]
38pub fn create2_address(sender: &Acc, salt: &Int, init_code_hash: &Int) -> Acc {
39    let mut preimage = Vec::with_capacity(85);
40    preimage.push(0xff);
41    preimage.extend_from_slice(sender.as_ref());
42    preimage.extend_from_slice(salt.as_ref());
43    preimage.extend_from_slice(init_code_hash.as_ref());
44    let hash = keccak256(&preimage);
45    Acc::from(&hash.as_ref()[12..])
46}