1use crate::H256;
2use ethereum_types::U256;
3use ethrex_crypto::keccak::keccak_hash;
4use hex::FromHexError;
5
6pub const ZERO_U256: U256 = U256([0, 0, 0, 0]);
7
8pub fn u256_from_big_endian(slice: &[u8]) -> U256 {
10 let mut padded = [0u8; 32];
11 padded[32 - slice.len()..32].copy_from_slice(slice);
12
13 let mut ret = [0; 4];
14
15 let mut u64_bytes = [0u8; 8];
16 for i in 0..4 {
17 u64_bytes.copy_from_slice(&padded[8 * i..(8 * i + 8)]);
18 ret[4 - i - 1] = u64::from_be_bytes(u64_bytes);
19 }
20
21 U256(ret)
22}
23
24pub fn u256_from_big_endian_const<const N: usize>(slice: [u8; N]) -> U256 {
28 const { assert!(N <= 32, "N must be less or equal to 32") };
29
30 let mut padded = [0u8; 32];
31 padded[32 - N..32].copy_from_slice(&slice);
32
33 let mut ret = [0u64; 4];
34
35 let mut u64_bytes = [0u8; 8];
36 for i in 0..4 {
37 u64_bytes.copy_from_slice(&padded[8 * i..(8 * i + 8)]);
38 ret[4 - i - 1] = u64::from_be_bytes(u64_bytes);
39 }
40
41 U256(ret)
42}
43
44#[inline(always)]
46pub fn u256_to_big_endian(value: U256) -> [u8; 32] {
47 let mut bytes = [0u8; 32];
48
49 for i in 0..4 {
50 let u64_be = value.0[4 - i - 1].to_be_bytes();
51 bytes[8 * i..(8 * i + 8)].copy_from_slice(&u64_be);
52 }
53
54 bytes
55}
56
57#[inline(always)]
58pub fn u256_to_h256(value: U256) -> H256 {
59 H256(u256_to_big_endian(value))
60}
61
62pub fn decode_hex(hex: &str) -> Result<Vec<u8>, FromHexError> {
63 let trimmed = hex.strip_prefix("0x").unwrap_or(hex);
64 hex::decode(trimmed)
65}
66
67pub fn keccak(data: impl AsRef<[u8]>) -> H256 {
68 H256(keccak_hash(data))
69}
70
71pub fn truncate_array<const N: usize, const M: usize>(data: [u8; N]) -> [u8; M] {
76 const { assert!(M <= N) };
77 let mut res = [0u8; M];
78 res.copy_from_slice(&data[..M]);
79 res
80}