← 返回
Web3与WASM 2026.03.09

函数定义与访问控制

Web3与WASM

学习目标

掌握 Solidity 函数定义、可见性修饰符、交易属性、modifier 和构造函数。


函数定义

一般形式

function fname([参数]) [可见性][交易属性][modifier...] returns(返回值) { ... }
  • 函数签名fname([参数]) —— 唯一标识一个函数
  • 返回值returns(返回值) —— 声明函数返回的类型

函数可见性

Solidity 提供四种可见性修饰符,控制函数的调用范围:

修饰符说明
public完全可见,内部和外部都能调用
private仅本合约可见,子合约也不能访问
internal本合约和子合约可见(类似 Java 的 protected)
external仅外部调用(通过 this 在内部调用会产生新的 message)

注意:变量默认 internal,函数默认 public。这与其他编程语言不同!

可见性示意图

A 合约
├── private   pri()    → 仅 A 内部
├── internal  inter()  → A 内部 + 子合约 B
├── public    pub()    → 全部可见    ←── C 合约可调用
└── external  ext()    → 仅外部      ←── C 合约可调用

B is A(继承 A)
├── inter()  可访问
└── pub()    可访问

交易属性

交易属性决定函数是否修改链上状态,直接影响 gas 消耗:

属性说明
默认(无修饰)写操作,全网广播,共识确认,消耗 gas
view只读操作,读取合约状态,不消耗 gas(外部调用时)
pure纯函数,与合约状态无关,只依赖输入参数

完整示例

// SPDX-License-Identifier: MIT
pragma solidity >=0.8.2 <0.9.0;

contract NumberStorage {
    uint public x;

    // 写操作(默认):修改状态,消耗 gas
    function setX(uint px) public {
        x = px;
    }

    // view:只读状态
    function getX() public view returns(uint) {
        return x;
    }

    // pure:与状态无关的纯计算
    function add(uint a, uint b) private pure returns(uint) {
        return a + b;
    }
}

函数修饰器(Modifier)

Modifier 类似 AOP(面向切面编程),常用于访问控制和前置条件检查。

  • require / revert 进行条件检查,不满足时回滚交易
  • _; 表示执行被修饰的函数体
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

contract NumberModifier {
    uint private number;

    modifier nonZero() {
        require(number != 0, "Number is zero and cannot be processed.");
        _;
    }

    function doubleNumber() public nonZero {
        number *= 2;
    }

    function resetNumber() public {
        number = 0;
    }
}

构造函数(Constructor)

构造函数在合约部署时调用一次,常用于初始化状态变量。msg.sender 是合约部署者的地址。

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

contract Constructor {
    address public owner;
    uint public x;

    constructor(uint _x) {
        owner = msg.sender;
        x = _x;
    }
}

综合实例:Ownable 合约

结合构造函数、modifier 和可见性控制,实现一个「仅拥有者可操作」的权限管理合约:

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

contract Ownable {
    address public owner;

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "not owner");
        _;
    }

    function setOwner(address _newOwner) external onlyOwner {
        require(_newOwner != address(0), "invalid address");
        owner = _newOwner;
    }
}

Counter 合约示例

一个简单的计数器合约,展示 external 可见性的使用:

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

contract Counter {
    uint public count;

    function inc() external {
        count += 1;
    }

    function dec() external {
        count -= 1;
    }
}