如何在Rust中将EVM存储槽H256拆分为u32、u128、u128
高效拆分EVM存储槽打包的uint256值
针对你给出的存储槽值 0x638d0490000000004b7cdeca2fe41a1b6411000000158fb5610df6aa553bfedb,最优的拆分方式是直接用位运算,避免字符串截取这类低效操作。以下是具体实现思路和代码示例:
核心逻辑
该存储槽按 uint32(最高32位)+ uint112(中间112位)+ uint112(最低112位) 的顺序打包为uint256,总位数32+112+112=256,刚好匹配uint256的长度。位运算直接操作数值底层,无额外内存开销,是性能最优的方案。
拆分步骤
- 提取uint32值:将uint256值右移224位(256-32),原最高32位会移动到最低位,直接转u32即可。
- 提取中间uint112值:先右移112位,再与112位全1的掩码(
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)做与运算,得到中间段后转u128。 - 提取最低uint112值:直接与112位全1的掩码做与运算,得到最低段后转u128。
代码示例
Rust(基于ethers库)
use ethers::types::U256; fn unpack_evm_slot(slot: U256) -> (u32, u128, u128) { // 112位掩码:2^112 - 1 const U112_MASK: U256 = U256::from(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); // 拆分最高32位为u32 let val_u32 = (slot >> 224).as_u32(); // 拆分中间112位为u128 let val_u128_mid = ((slot >> 112) & U112_MASK).as_u128(); // 拆分最低112位为u128 let val_u128_low = (slot & U112_MASK).as_u128(); (val_u32, val_u128_mid, val_u128_low) } // 测试调用 fn main() { let slot = U256::from_str("0x638d0490000000004b7cdeca2fe41a1b6411000000158fb5610df6aa553bfedb").unwrap(); let (val1, val2, val3) = unpack_evm_slot(slot); println!("u32值: 0x{:x}", val1); println!("中间u128值: 0x{:x}", val2); println!("最低u128值: 0x{:x}", val3); }
Solidity
pragma solidity ^0.8.0; contract SlotUnpacker { function unpackSlot(uint256 slot) public pure returns (uint32, uint128, uint128) { uint32 val1 = uint32(slot >> 224); uint128 val2 = uint128((slot >> 112) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); uint128 val3 = uint128(slot & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return (val1, val2, val3); } }
Python
def unpack_evm_slot(slot_hex: str) -> tuple[int, int, int]: slot = int(slot_hex, 16) # 112位掩码 u112_mask = (1 << 112) - 1 val_u32 = (slot >> 224) & 0xFFFFFFFF val_u128_mid = (slot >> 112) & u112_mask val_u128_low = slot & u112_mask return (val_u32, val_u128_mid, val_u128_low) # 测试调用 slot_hex = "0x638d0490000000004b7cdeca2fe41a1b6411000000158fb5610df6aa553bfedb" val1, val2, val3 = unpack_evm_slot(slot_hex) print(f"u32值: 0x{val1:x}") print(f"中间u128值: 0x{val2:x}") print(f"最低u128值: 0x{val3:x}")
说明
- 位运算的时间复杂度为O(1),远优于字符串截取、补零后转换的方案,尤其适合批量处理存储槽的场景。
- 拆分后的数值长度均小于目标类型(如112位 < 128位),不会出现溢出问题。
内容的提问来源于stack exchange,提问作者0xDmtri
相关产品推荐
相关产品推荐

