Solidity

函式沒有參數時如何生成簽名?

  • December 3, 2020

當函式有參數時,Solidity 通過在函式名稱後面添加參數類型,在括號之間,並獲取結果字元串的 keccak256 雜湊來生成其簽名。舉個例子:

sendMessage(string,address)

這個函式的簽名是 0xc48d6d5e。

但是,如果“字元串”和“地址”參數不存在怎麼辦?Solidity 會採用 , 或其他的 keccak256 雜湊sendMessagesendMessage()

一個簡單的測試表明答案是"sendMessage()"

Solidity 合約:

pragma solidity 0.6.12;

contract MyContract {
   uint256 private constant SUCCESS = 42;
   uint256 private constant FAILURE = 84;

   function sendMessage() external pure returns (uint256) {
       return SUCCESS;
   }

   function test(bytes4 funcSelector) external view returns (uint256) {
       bytes memory data = abi.encodeWithSelector(funcSelector);
       (bool success, bytes memory returnData) = address(this).staticcall(data);

       if (success && returnData.length == 32)
           return abi.decode(returnData, (uint256));

       return FAILURE;
   }
}

松露 5.x 腳本:

contract("MyContract", () => {
   it("test", async () => {
       const myContract = await artifacts.require("MyContract").new();
       const success = await myContract.test(web3.utils.keccak256("sendMessage()"));
       const failure = await myContract.test(web3.utils.keccak256("sendMessage"));
       console.log(success.toString()); // prints 42
       console.log(failure.toString()); // prints 84
   });
});

這是一種更簡單的方法,甚至無需與合約互動:

const Web3 = require("web3");

const web3 = new Web3();

const abi = [{
   "inputs":[],
   "name":"sendMessage",
   "outputs":[],
   "stateMutability":"pure",
   "type":"function"
}];

const contract = new web3.eth.Contract(abi);

console.log(Web3.utils.keccak256("sendMessage").slice(0, 10));
console.log(Web3.utils.keccak256("sendMessage()").slice(0, 10));

for (const method of contract._jsonInterface)
   if (method.name == "sendMessage")
       console.log(method.signature);

列印輸出是:

0x736c24a9
0xe5aed28a
0xe5aed28a

引用自:https://ethereum.stackexchange.com/questions/90721