Skip to content
sam bacha edited this page May 8, 2022 · 2 revisions

Welcome to the openevm wiki!

The log hash is keccak(rlp(logs[])), https://github.com/ethereum/go-ethereum/blob/356bbe343a30789e77bb38f25983c8f2f2bfbb47/cmd/evm/internal/t8ntool/execution.go#L255

/// Returns the log hash for all `logs`
///
/// The log hash is `keccak(rlp(logs[]))`, <https://github.com/ethereum/go-ethereum/blob/356bbe343a30789e77bb38f25983c8f2f2bfbb47/cmd/evm/internal/t8ntool/execution.go#L255>
pub fn log_rlp_hash(logs: Vec<Log>) -> H256 {
    let mut stream = RlpStream::new();
    stream.begin_unbounded_list();
    for log in logs {
        stream.begin_list(3);
        stream.append(&log.address);
        stream.append_list(&log.topics);
        stream.append(&log.data);
    }
    stream.finalize_unbounded_list();
    let out = stream.out().freeze();

    let out = ethers::utils::keccak256(out);
    H256::from_slice(out.as_slice())
}

pub fn state_merkle_trie_root(
    accounts: &Map<Address, AccountInfo>,
    storage: &Map<Address, Map<U256, U256>>,
) -> H256 {
    let vec = accounts
        .iter()
        .map(|(address, info)| {
            let storage = storage.get(address).cloned().unwrap_or_default();
            let storage_root = trie_account_rlp(info, storage);
            (*address, storage_root)
        })
        .collect::<Vec<_>>();

    trie_root(vec)
}

/// Returns the RLP for this account.
pub fn trie_account_rlp(info: &AccountInfo, storage: Map<U256, U256>) -> Bytes {
    let mut stream = RlpStream::new_list(4);
    stream.append(&info.nonce);
    stream.append(&info.balance);
    stream.append(&{
        sec_trie_root(storage.into_iter().filter(|(_k, v)| v != &U256::zero()).map(|(k, v)| {
            let mut temp: [u8; 32] = [0; 32];
            k.to_big_endian(&mut temp);
            (H256::from(temp), rlp::encode(&v))
        }))
    });
    stream.append(&info.code_hash.as_bytes());
    stream.out().freeze()
}
Clone this wiki locally