049.Solidity入门——36函数签名

文章介绍了Solidity中函数签名的作用,它是函数的唯一标识,由函数名和参数类型组成。哈希函数如Keccak256用于生成签名的哈希值,前四个字节作为函数选择器。在合约调用时,选择器用于决定执行哪个函数。文中通过一个示例合约展示了如何处理函数选择器的匹配和调用过程。
摘要由CSDN通过智能技术生成

函数签名是用来标识函数的唯一标识符,它由函数的名称参数类型组成。例如,函数 foo(uint256 a, string memory b) 的签名是 foo(uint256,string)。

Solidity 使用特定的哈希函数(例如 Keccak256)来计算函数签名的哈希值,然后取前四个字节作为函数选择器。函数选择器用于在调用合约时确定要执行哪个函数。

下面演示如何使用函数签名和选择器:

contract FunctionSignature {
    // 定义一个事件,用于记录调用的结果
    event Called(string name);

    // 定义一个公开的 foo 函数,接受两个参数
    function foo(uint256 a, string memory b) public {
        // 触发 Called 事件,传入 "foo" 作为参数
        emit Called("foo");
    }

    // 定义一个公开的 bar 函数,接受一个参数
    function bar(address c) public {
        // 触发 Called 事件,传入 "bar" 作为参数
        emit Called("bar");
    }

    // 定义一个外部的 fallback 函数,用于处理没有匹配到其他函数的调用
    fallback() external {
        // 获取 msg.data 的长度(字节数)
        uint256 length = msg.data.length;
        // 如果长度小于 4,则说明没有提供有效的函数选择器,直接返回
        if (length < 4) {
            return;
        }
        // 否则,从 msg.data 中取出前四个字节作为选择器,并存储到变量 selector 中
        bytes4 selector;
        assembly {
            selector := mload(add(msg.data, 0x20))
        }
        // 判断选择器是否等于 foo 函数的签名哈希值(前四个字节)
        if (selector == bytes4(keccak256("foo(uint256,string)"))) {
            // 如果是,则调用 foo 函数,并将 msg.data 中剩余的字节作为参数传入
            (bool success,) = address(this).delegatecall(
                abi.encodePacked(bytes4(keccak256("foo(uint256,string)")), msg.data[4:])
            );
            require(success);
            return;
        }
         // 判断选择器是否等于 bar 函数的签名哈希值(前四个字节)
         if (selector == bytes4(keccak256("bar(address)"))) {
             // 如果是,则调用 bar 函数,并将 msg.data 中剩余的字节作为参数传入
             (bool success,) = address(this).delegatecall(
                 abi.encodePacked(bytes4(keccak256("bar(address)")), msg.data[4:])
             );
             require(success);
             return;
         }
         // 如果都不匹配,则抛出异常
         revert();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值