..

计算solidity的方法哈希

在 solidity 的合约代码中,由ABI来决定一怎么样的方式和evm进行交互。 其中包括关于 solidity 方法的hash计算。 看一个 solidity 的代码


pragma solidity >=0.7.0 <0.9.0;

/**
 * @title Storage
 * @dev Store & retrieve value in a variable
 */
contract Storage {

    uint256 number;

    /**
     * @dev Store value in variable
     * @param num value to store
     */
    function store(uint256 num) public {
        number = num;
    }

    /**
     * @dev Return value 
     * @return value of 'number'
     */
    function retrieve() public view returns (uint256){
        return number;
    }
}

evm 通过方法的签名来找到要调用的方法。 其中,一个函数调用数据的前 4 字节,指定了要调用的函数。 也就是函数签名的 Keccak(SHA-3)哈希的前 4 字节(高位在左的大端序)。 对函数签名有几个要求

  • 返回类型不属于函数签名
  • 函数签名只包括方法名和用括号括起来的参数类型列表
  • 参数类型列表用逗号分隔开
  • 不能包含空格

综上信息,函数的签名计算公式如下

function_hash = Keccak(function_sig)[0..4]

以上代码为例, 有效的方法签名包括

function_hash = Keccab(retrieve())[0..4]
function_hash = Keccab(store(uint256))[0..4]

jlib-rs 库中,我用Rust实现了一下,包含了测试用例和example, 可以参考下。1