
(一)solidity基本语法规则
最近在玩solidity,所以记录一下solidity的一些语法规则
1、可见性修饰符
控制函数/变量的访问边界
修饰符 | 访问范围 | 典型场景 |
---|---|---|
public | 合约内外均可访问(自动生成状态变量的 getter 函数) | 公开接口方法(balanceOf() ) |
external | 只能通过外部交易调用(合约内部不可直接调用) | 回调函数(receive() ) |
internal | 仅限当前合约及继承合约(类似其他语言的 protected ) |
内部权限检查(_validate() ) |
private | 仅限当前合约内部(继承合约不可见) | 敏感数据操作(_secretKey ) |
2、状态可变性修饰符
定义函数对链状态的读写权限
修饰符 | 状态交互规则 | Gas 消耗 | 适用场景 |
---|---|---|---|
pure | 禁止读写状态变量和交易上下文 | 0 Gas | 数学计算(sqrt(x) ) |
view | 只读状态变量(可访问 block.timestamp ) |
0 Gas | 数据查询(getUserInfo() ) |
payable | 允许接收 ETH(msg.value ) |
按操作消耗 Gas | 支付功能(deposit() ) |
状态变量不加修饰符,默认为internal;在solidity > 0.5后,函数的声明必须加上修饰符
3、继承修饰符
管理合约继承体系中的函数覆盖
修饰符 | 作用规则 | 使用场景 |
---|---|---|
virtual | 标记函数可被子合约覆盖(基类函数必须声明) | 可扩展的基类方法(_beforeTransfer() ) |
override | 声明函数覆盖父合约方法(需完全匹配父函数签名) | 实现接口(IERC20.transfer() ) |
继承示例
1 | // 基类合约 |
4.关键规则总结
A.标准修饰符顺序:可见性 → 状态可变性 → 继承
B.状态访问限制函数禁止以下操作
1 | uint x = storageVar; // 禁止读取状态 |
C.多重继承需明确指定父合约
1 | contract Z is X, Y { |
5.存储位置
概念 | 控制权 | 读写权限 | 典型场景 | 是否消耗 Gas |
---|---|---|---|---|
storage | 开发者 | 可读可写 | 合约状态变量 | 高(修改时) |
memory | 开发者 | 可读可写 | 函数内临时数据 | 低 |
calldata | 开发者 | 只读 | 外部函数参数 | 最低 |
stack | EVM | 自动管理 | 局部变量和计算中间结果 | 低 |
logs | 开发者 | 仅写入(emit) | 事件日志记录 | 中 |
code | EVM | 只读 | 合约字节码存储 | 无 |
6.常用数据结构
数据结构 | 作用描述 | 典型使用场景 |
---|---|---|
静态数组 | 固定长度的数组,元素类型和数量在声明时确定 | 存储固定数量的配置参数(如颜色代码、权限等级) |
动态数组 | 长度可变的数组,支持动态添加或删除元素 | 管理用户列表、动态生成的数据集合(如投票记录、订单历史) |
结构体(Struct) | 自定义复合类型,可组合多个不同数据类型的字段 | 表示复杂实体(如用户信息、订单详情)、嵌套数据模型(如商品分类下的子分类) |
映射(Mapping) | 键值对存储结构,支持通过键快速查找值(但无法遍历键) | 地址到余额的映射(mapping(address => uint) )、唯一ID到实体的关联(如NFT) |
枚举(Enum) | 定义一组命名的常量集合,提升代码可读性 | 状态机标识(如订单状态:Created /Paid /Shipped )、用户角色分类 |
字符串(String) | 存储UTF-8编码的文本数据 | 用户名、描述字段、日志消息(如错误提示) |
字节数组(Bytes) | 存储二进制数据(bytes 为动态长度,bytes32 为固定长度) |
哈希值存储(bytes32 )、加密消息、文件内容处理 |
合约类型(Contract) | 引用其他合约地址,支持跨合约调用 | 代币合约交互(如IERC20(token).transfer() )、可升级代理合约逻辑 |
当函数参数涉及引用类型(如 string、array、struct)时,必须显式声明其数据位置(memory 或 calldata)
Solidity 0.5.0+ 版本严格要求所有引用类型参数必须明确数据位置,而旧版本允许隐式处理。若未指定,编译器会强制报错
7.组合使用场景示例
- 结构体 + 映射 + 动态数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15contract UserManager {
struct User {
address wallet;
uint256 score;
bool isActive;
}
mapping(address => User) private users; // 地址到用户的快速查找
address[] public userList; // 遍历所有用户地址
function addUser(address _wallet) public {
users[_wallet] = User(_wallet, 0, true);
userList.push(_wallet);
}
} - 枚举 + 结构体
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19contract OrderSystem {
enum OrderStatus {
Created,
Paid,
Shipped
}
struct Order {
uint256 id;
address buyer;
OrderStatus status;
}
Order[] public orders; // 动态数组存储订单
function shipOrder(uint256 _id) public {
orders[_id].status = OrderStatus.Shipped;
}
} - 映射 + 动态数组(白名单管理)
1
2
3
4
5
6
7
8
9
10contract Whitelist {
mapping(address => bool) public isWhitelisted;
address[] public whitelistedAddresses; // 遍历白名单地址
function addToWhitelist(address _addr) public {
require(!isWhitelisted[_addr], "Already whitelisted");
isWhitelisted[_addr] = true;
whitelistedAddresses.push(_addr);
}
}
- Title: (一)solidity基本语法规则
- Author: viEcho
- Created at : 2025-04-13 18:21:20
- Updated at : 2025-05-11 16:34:55
- Link: https://viecho.github.io/2025/0413/solidity-base-programming-rules.html
- License: This work is licensed under CC BY-NC-SA 4.0.
Comments