兼容Hash Solidity

这个合约展示了在 Cairo 中进行 Keccak 哈希处理以匹配 Solidity 的 keccak256。尽管两者都使用 Keccak,但它们的字节序不同:Cairo 是小端序,Solidity 是大端序。该合约通过使用 keccak_u256s_be_inputs 以大端序进行哈希处理,并使用 u128_byte_reverse 反转结果的字节来实现兼容。

例如:

#[starknet::interface]
trait ISolidityHashExample<TContractState> {
    fn hash_data(ref self: TContractState, input_data: Span<u256>) -> u256;
}


#[starknet::contract]
mod SolidityHashExample {
    use keccak::{keccak_u256s_be_inputs};
    use array::Span;

    #[storage]
    struct Storage {}

    #[abi(embed_v0)]
    impl SolidityHashExample of super::ISolidityHashExample<ContractState> {
        fn hash_data(ref self: ContractState, input_data: Span<u256>) -> u256 {
            let hashed = keccak_u256s_be_inputs(input_data);

            // Split the hashed value into two 128-bit segments
            let low: u128 = hashed.low;
            let high: u128 = hashed.high;

            // Reverse each 128-bit segment
            let reversed_low = integer::u128_byte_reverse(low);
            let reversed_high = integer::u128_byte_reverse(high);

            // Reverse merge the reversed segments back into a u256 value
            let compatible_hash = u256 { low: reversed_high, high: reversed_low };

            compatible_hash
        }
    }
}

Remix 上测试这个合约.

Last change: 2023-11-21, commit: 58cde22