19. Solidity:函数选择器(函数签名)

2023-10-09  本文已影响0人  泡泡龙吐泡泡

19.1 selector

当我们调用智能合约时,本质上是向目标合约发送了一段calldata,在remix中发送一次交易后,可以在详细信息中看见input即为此次交易的calldata。

发送的calldata中前4个字节是selector(函数选择器)。
示例代码,将msg.data作为事件发出:

contract Selector {
    address public addr;
    event Log(bytes data);

    function selector(address _addr) external {
        addr = _addr;
        emit Log(msg.data);
    }
}

remix日志中的input:


input

Log信息(msg.data):

[
    {
        "from": "0xc5c97AAd92a962396229cbC8392e62585B04DfB3",
        "topic": "0xafabcf2dd47e06a477a89e49c03f8ebe8e0a7e94f775b25bbb24227c9d0110b2",
        "event": "Log",
        "args": {
            "0": "0x91fa5ace0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4",
            "data": "0x91fa5ace0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4"
        }
    }
]

可见input信息和全局变量msg.data相同,都是此次调用函数的calldata:

0x91fa5ace0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4

前四个字节为函数选择器:
0x91fa5ace
后面32字节为传入的参数(20字节的地址补零):
0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4

calldata作用是:告诉智能合约,要调用哪个函数,以及参数是什么。

19.2 函数签名、selector和method id

实现一个函数获取上述例子中selector()函数的method id:

    function getSelector() external pure returns (bytes4){
        return bytes4(keccak256("selector(address)"));
    }

调用函数的返回值和函数选择器相同,为0x91fa5ace。Solidity中通过函数选择器(selector)匹配method id的方式确定要调用的函数。

19.3 selector的使用

我们可以利用selector来调用目标函数。例如我想调用selector()函数,我只需要利用abi.encodeWithSelector将selector()函数的method id作为selector和参数打包编码,传给call函数:

    function useSelector(address _addr) external returns (bool) {
        (bool success, ) = address(this).call(abi.encodeWithSelector(0x91fa5ace, _addr));
        return success;
    }

调用selector()函数成功,输出的Log:

[
    {
        "from": "0xf02A102153DDf132032B7De5D19F43aA049052Dd",
        "topic": "0xafabcf2dd47e06a477a89e49c03f8ebe8e0a7e94f775b25bbb24227c9d0110b2",
        "event": "Log",
        "args": {
            "0": "0x91fa5ace0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4",
            "data": "0x91fa5ace0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4"
        }
    }
]
上一篇 下一篇

猜你喜欢

热点阅读