在 Solidity 中,函数是执行特定任务的代码块。函数可以接受参数,并且可以返回值。函数在智能合约中起着核心作用,用于实现合约的逻辑。

以下是一个简单的 Solidity 函数的例子:

function add(uint x, uint y) public pure returns (uint) {
    uint sum = x + y;
    return sum;
}

在这个例子中,add 是函数名,uint x, uint y 是参数,public 是函数的可见性修饰符,pure 是函数的状态修饰符,returns (uint) 表示函数返回的类型。

以下是 Solidity 函数的一些重要特性:

  1. 函数可见性:函数可见性决定了函数可以在哪里被调用。有四种类型的可见性:publicprivateinternalexternalpublic 函数可以在任何地方被调用,private 函数只能在当前合约中被调用,internal 函数可以在当前合约和继承的合约中被调用,external 函数只能从合约外部被调用。
  2. 函数状态修饰符:函数状态修饰符提供了函数如何和合约状态交互的信息。有四种状态修饰符:pureviewpayablenonpayablepure 函数不读取也不修改状态,view 函数可以读取但不修改状态,payable 函数可以接收 Ether,并且可以修改状态,nonpayable 函数不接收 Ether,但可以修改状态。
  3. 函数返回值:函数可以返回一个或多个值。返回值在函数声明中用 returns 关键字指定。
  4. 函数参数:函数可以接受参数,参数类型必须在函数声明时指定。
  5. 函数重载:Solidity 支持函数重载,即在同一个合约中可以有多个同名函数,只要它们的参数类型或数量不同即可。
  6. 构造函数:每个合约可以有一个特殊的函数叫做构造函数,它在合约创建时被调用。构造函数的名字必须和合约名字相同,或者使用 constructor 关键字。
  7. 回退函数:回退函数是合约中没有名字的函数,当合约收到 Ether 但没有匹配到任何函数时,回退函数被调用。每个合约最多只能有一个回退函数。
  8. 接收函数:接收函数是一个特殊的函数,它在合约收到 Ether 并且没有数据时被调用。每个合约最多只能有一个接收函数,它必须使用 receive 关键字并且必须是 external payable

在 Solidity 中,函数状态修饰符用于描述函数对合约状态的访问和修改能力。它们帮助开发者理解函数的行为,并确保函数的正确使用。以下是四种函数状态修饰符及其作用:

  1. pure: 这个修饰符表示函数不会读取或修改状态。也就是说,它不会读取或写入合约的状态变量,也不会调用任何非 pure 的函数。这样的函数只依赖于其输入参数,并返回一个值。这意味着,对于相同的输入,pure 函数总是返回相同的结果。
  2. view: 这个修饰符表示函数可以读取但不能修改状态。也就是说,它可以读取合约的状态变量,但不能修改它们,也不能调用任何修改状态的函数。这样的函数通常用于返回合约的状态变量或计算基于状态变量的结果。
  3. payable: 这个修饰符表示函数可以接收 Ether 并修改状态。在 Ethereum 中,当一个函数被标记为 payable 时,它可以在调用时附带 Ether。这样的函数通常用于接收和处理 Ether 支付。
  4. nonpayable: 这个修饰符表示函数不能接收 Ether,但可以修改状态。这是函数的默认状态,如果没有指定其他修饰符,函数就是 nonpayable 的。这样的函数可以修改合约的状态变量,但不能在调用时接收 Ether。

这些修饰符帮助开发者理解和控制函数的行为,确保函数的正确使用。例如,如果你看到一个被标记为 view 的函数,你就知道它不会修改合约的状态。如果你看到一个被标记为 payable 的函数,你就知道它可以接收 Ether。

完整示例

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

contract FunctionExample {
    // 定义事件,合约收到转账时调用
    event Received(address sender, uint256 amount);

    // 简单的加法示例
    function add(uint256 _x, uint256 _y) public pure returns (uint256) {
        return _x + _y;
    }

    // 返回多个值
    function returnMany()
        public
        view
        returns (
            uint256,
            address,
            bool
        )
    {
        return (1, msg.sender, true);
    }

    // 多入参函数调用
    function manyInput(
        bool _a,
        address _addr,
        uint256 _c
    ) public pure returns (uint256) {}

    // 调用,入参顺序与函数定义一致
    function callFunc() public pure returns (uint256) {
        return manyInput(false, address(0), 0);
    }

    // 入参顺序与函数定义不一致,通过key=>value形式调用
    function callFunc2() public pure returns (uint256) {
        return manyInput({_addr: address(0), _a: true, _c: 0});
    }

    // donate 接收转账
    function donate() public payable {
        // ....
        emit Received(msg.sender, msg.value);
    }
}

孟斯特

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。

Author: mengbin

blog: mengbin

Github: mengbin92

cnblogs: 恋水无意

腾讯云开发者社区:孟斯特