合约结构
在 Solidity 中,合约类似于面向对象编程语言中的类。 每个合约中可以包含 状态变量, 函数, 函数修饰器, 事件, 错误, 结构类型 和 枚举类型 的声明,且合约可以从其他合约继承。
状态变量
指其值被永久地存储在合约存储中的变量。
csharp
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
contract SimpleStorage {
uint storedData; // 状态变量
// ...
}
函数
函数是代码的可执行单位。 通常在合约内定义函数,但它们也可以被定义在合约之外。
csharp
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.1 <0.9.0;
contract SimpleAuction {
function bid() public payable { // 函数
// ...
}
}
// 定义在合约之外的辅助函数
function helper(uint x) pure returns (uint) {
return x * 2;
}
函数修饰器
函数修饰器(Function Modifier)是 Solidity 中的一个关键语法功能,用于在函数执行前插入一段"通用逻辑"代码,常用于:
- 权限控制(如 onlyOwner)
- 重入锁
- 状态校验(如合约未暂停)
ini
modifier onlyOwner() {
require(msg.sender == owner, "Not the owner");
_; // 占位符:表示函数的主体将在这里执行
}
可以把 modifier 理解成一个函数前的"中间层拦截器"。
常见内置修饰器(OpenZeppelin 中)
修饰器 | 功能描述 |
---|---|
onlyOwner |
仅合约拥有者可调用 |
nonReentrant |
防止重入攻击(reentrancy) |
whenNotPaused |
合约未暂停时可用 |
事件
智能合约中用于向链下应用(如前端 DApp)发送日志消息的机制,方便监听和响应链上的行为。
事件的意义和用途
- ✅ 链下监听交易行为(如前端用
web3.js
/ethers.js
监听事件) - ✅ 提高审计和可读性
- ✅ 提高性能(事件不存储到链状态,不消耗 gas 存储费)
- ✅ 做成"通知"机制,告诉外部世界状态变化了
javascript
contract.on("Transferred", (from, to, amount) => {
console.log(`🚀 ${from} transferred ${amount} to ${to}`);
});
indexed
的作用
indexed
参数可以用于前端筛选事件日志- 最多只能有 三个 indexed 参数
event MyEvent(address indexed user, uint256 value);
前端可以筛选出所有 user == xxx
的事件,而不必遍历所有日志。
错误
错误(类型)允许您为失败情况定义描述性的名称和数据。 错误(类型)可以在 回滚声明 中使用。 与字符串描述相比,错误(类型)要便宜得多,并允许您对额外的数据进行编码。
结构类型
结构类型是可以将几个变量分组的自定义类型
csharp
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
contract Ballot {
struct Voter { // 结构
uint weight;
bool voted;
address delegate;
uint vote;
}
}
枚举类型
arduino
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
contract Purchase {
enum State { Created, Locked, Inactive } // 枚举
}