Solidity基础语法 #
一、注释 #
1.1 单行注释 #
使用//进行单行注释:
solidity
// 这是一个单行注释
uint256 public count; // 变量声明后的注释
1.2 多行注释 #
使用/* */进行多行注释:
solidity
/*
* 这是一个多行注释
* 可以跨越多行
* 用于详细说明
*/
contract MyContract {
/*
合约逻辑
在这里实现
*/
}
1.3 文档注释(NatSpec) #
Solidity支持Ethereum Natural Language Specification(NatSpec)格式的文档注释:
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @title 简单存储合约
* @author 开发者名称
* @notice 这是一个用于演示的合约
* @dev 详细开发说明
*/
contract SimpleStorage {
uint256 private _count;
/**
* @notice 设置计数值
* @param newCount 新的计数值
* @dev 只有owner可以调用此函数
*/
function setCount(uint256 newCount) public {
_count = newCount;
}
/**
* @notice 获取当前计数值
* @return 当前存储的计数值
*/
function getCount() public view returns (uint256) {
return _count;
}
}
1.4 NatSpec标签 #
| 标签 | 说明 | 使用场景 |
|---|---|---|
| @title | 合约标题 | 描述合约用途 |
| @author | 作者信息 | 标注开发者 |
| @notice | 用户说明 | 面向终端用户 |
| @dev | 开发说明 | 面向开发者 |
| @param | 参数说明 | 函数参数 |
| @return | 返回值说明 | 函数返回值 |
| @inheritdoc | 继承文档 | 从父合约继承文档 |
| @custom | 自定义标签 | 扩展用途 |
二、标识符 #
2.1 命名规则 #
标识符用于命名合约、函数、变量等,必须遵循以下规则:
| 规则 | 说明 | 示例 |
|---|---|---|
| 字符组成 | 字母、数字、下划线 | myVar, _count, value1 |
| 首字符 | 字母或下划线 | name, _private |
| 大小写敏感 | Name和name不同 |
区分对待 |
| 不能是关键字 | 避免保留字 | 不能用contract作变量名 |
2.2 合法标识符 #
solidity
// 合法的标识符
contract MyContract {}
function myFunction() {}
uint256 my_variable;
uint256 _privateVar;
uint256 count1;
2.3 非法标识符 #
solidity
// 非法的标识符
// uint256 1count; // 不能以数字开头
// uint256 my-var; // 不能包含连字符
// uint256 contract; // 不能使用关键字
// uint256 my variable; // 不能包含空格
三、关键字 #
3.1 保留关键字 #
Solidity保留关键字不能用作标识符:
solidity
// 这些是关键字,不能用作变量名
// abstract, after, alias, apply, auto, byte, case, catch, constant
// contract, constructor, continue, contract, days, else, emit, enum
// ether, event, external, fallback, false, finney, for, function
// gwei, hours, if, immutable, import, indexed, interface, internal
// is, let, mapping, match, memory, minutes, modifier, new, override
// payable, pragma, private, public, pure, receive, return, returns
// revert, seconds, storage, struct, suicode, switch, this, throw
// true, try, type, using, var, view, virtual, weeks, wei, while
// years
3.2 关键字分类 #
声明类关键字:
| 关键字 | 用途 | 示例 |
|---|---|---|
| contract | 声明合约 | contract Foo {} |
| interface | 声明接口 | interface IERC20 {} |
| library | 声明库 | library Math {} |
| struct | 声明结构体 | struct User {} |
| enum | 声明枚举 | enum Status {} |
| event | 声明事件 | event Transfer() {} |
| modifier | 声明修饰器 | modifier onlyOwner() {} |
可见性关键字:
| 关键字 | 说明 |
|---|---|
| public | 公开,任何地方可访问 |
| private | 私有,仅本合约可访问 |
| internal | 内部,本合约及子合约可访问 |
| external | 外部,仅外部可调用 |
状态修饰关键字:
| 关键字 | 说明 |
|---|---|
| view | 只读,不修改状态 |
| pure | 纯函数,不读取也不修改状态 |
| payable | 可接收ETH |
存储位置关键字:
| 关键字 | 说明 |
|---|---|
| storage | 永久存储 |
| memory | 临时内存 |
| calldata | 调用数据,只读 |
其他关键字:
| 关键字 | 用途 |
|---|---|
| constructor | 构造函数 |
| fallback | 回退函数 |
| receive | 接收函数 |
| this | 当前合约 |
| super | 父合约 |
| import | 导入文件 |
| pragma | 编译指示 |
| using | 库使用声明 |
四、代码规范 #
4.1 命名约定 #
合约命名:
solidity
// 使用大驼峰命名(PascalCase)
contract TokenVault {}
contract SimpleStorage {}
contract ERC20Token {}
函数命名:
solidity
// 使用小驼峰命名(camelCase)
function getBalance() public view returns (uint256) {}
function transferTokens() public {}
function calculateInterest() private pure returns (uint256) {}
变量命名:
solidity
// 状态变量:小驼峰,私有变量前加下划线
uint256 public totalSupply;
uint256 private _balance;
address internal _owner;
// 局部变量:小驼峰
function calculate() public {
uint256 tempValue = 100;
uint256 result = tempValue * 2;
}
// 常量:全大写下划线分隔
uint256 public constant MAX_SUPPLY = 1000000;
bytes32 public constant DOMAIN_SEPARATOR = keccak256("...");
事件命名:
solidity
// 使用大驼峰命名
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
修饰器命名:
solidity
// 使用小驼峰命名,表达限制条件
modifier onlyOwner() {
require(msg.sender == owner, "Not owner");
_;
}
modifier nonZeroAddress(address _addr) {
require(_addr != address(0), "Zero address");
_;
}
modifier whenNotPaused() {
require(!paused, "Contract is paused");
_;
}
4.2 代码布局 #
缩进:
solidity
// 使用4个空格缩进
contract Example {
uint256 public value;
function setValue(uint256 _value) public {
value = _value;
}
}
空行:
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0; // 空行分隔声明
contract Example { // 空行分隔合约
uint256 public value1;
uint256 public value2; // 相关变量可不空行
event ValueChanged(uint256 newValue); // 空行分隔不同类型
modifier validValue(uint256 _value) {
require(_value > 0, "Invalid value");
_;
}
function setValue(uint256 _value) public validValue(_value) {
value1 = _value;
emit ValueChanged(_value);
}
function getValue() public view returns (uint256) {
return value1;
}
}
行长度:
solidity
// 建议每行不超过120字符
// 长行可以换行
function veryLongFunctionName(
address _token,
address _recipient,
uint256 _amount
) public returns (bool) {
// 函数体
}
函数声明顺序:
solidity
contract OrderedContract {
// 1. 状态变量
uint256 public count;
address public owner;
// 2. 事件
event CountChanged(uint256 newCount);
// 3. 修饰器
modifier onlyOwner() {
require(msg.sender == owner, "Not owner");
_;
}
// 4. 构造函数
constructor() {
owner = msg.sender;
}
// 5. 接收函数
receive() external payable {}
// 6. 回退函数
fallback() external payable {}
// 7. external函数
function externalFunction() external {}
// 8. public函数
function publicFunction() public {}
// 9. internal函数
function internalFunction() internal {}
// 10. private函数
function privateFunction() private {}
}
4.3 最佳实践 #
1. 使用明确的可见性:
solidity
// 不推荐:省略可见性
function getValue() returns (uint256) {
return value;
}
// 推荐:明确指定可见性
function getValue() public view returns (uint256) {
return value;
}
2. 使用NatSpec文档:
solidity
// 推荐:添加文档注释
/**
* @notice 转账代币给指定地址
* @param to 接收地址
* @param amount 转账数量
* @return 是否成功
*/
function transfer(address to, uint256 amount) public returns (bool) {
// 实现
}
3. 使用有意义的命名:
solidity
// 不推荐:无意义命名
function f(address a, uint256 x) public {}
// 推荐:有意义命名
function transferTo(address recipient, uint256 amount) public {}
4. 保持函数简洁:
solidity
// 推荐:单一职责
function setCount(uint256 newCount) public onlyOwner {
count = newCount;
emit CountChanged(newCount);
}
// 不推荐:函数过长
function doManyThings(uint256 a, uint256 b, uint256 c) public {
// 100行代码...
}
五、表达式与语句 #
5.1 表达式 #
solidity
// 算术表达式
uint256 result = a + b * c;
// 比较表达式
bool isEqual = a == b;
bool isGreater = a > b;
// 逻辑表达式
bool isValid = isActive && hasPermission;
bool canProceed = !isPaused || isOwner;
// 位运算表达式
uint256 masked = value & mask;
uint256 shifted = value << 2;
5.2 语句 #
solidity
// 声明语句
uint256 value;
address owner;
// 赋值语句
value = 100;
owner = msg.sender;
// 表达式语句
value++;
// 块语句
{
uint256 temp = value;
value = temp * 2;
}
六、导入语句 #
6.1 导入方式 #
solidity
// 导入整个文件
import "./MyContract.sol";
// 导入并重命名
import * as MyLib from "./MyLib.sol";
// 导入特定符号
import {MyContract, MyStruct} from "./MyContract.sol";
// 从npm包导入
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
6.2 导入路径 #
solidity
// 相对路径
import "./SameDirectory.sol";
import "../ParentDirectory.sol";
import "./subdirectory/Child.sol";
// 绝对路径(从node_modules)
import "@openzeppelin/contracts/access/Ownable.sol";
七、总结 #
语法要点:
| 类别 | 要点 |
|---|---|
| 注释 | 单行//、多行/* */、NatSpec |
| 标识符 | 字母、数字、下划线,不能以数字开头 |
| 关键字 | 保留字,不能用作标识符 |
| 命名 | 大驼峰(合约)、小驼峰(函数/变量) |
| 可见性 | public、private、internal、external |
代码规范:
- 使用有意义的命名
- 添加NatSpec文档
- 保持代码简洁
- 遵循声明顺序
下一步,让我们学习Solidity的数据类型!
最后更新:2026-03-27