函数定义与访问控制
学习目标
掌握 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;
}
}
主题测试文章,只做测试使用。发布者:Walker,转转请注明出处:https://walker-learn.xyz/archives/7491