Solidity 简介

Solidity 代码结构

    Solidity 智能合约的代码具有清晰的结构化组织方式,下面我将详细介绍一个标准 Solidity 合约的完整结构及各部分的作用。


1、版本声明和许可标识

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

SPDX 许可证标识:指定合约的开源许可证类型(如 MIT、GPL 等)

pragma 版本指令:声明编译器版本要求

  • 0.8.17: 严格使用0.8.17版本

  • ^0.8.0:表示0.8.0及以上但不包括0.9.0

  • >=0.7.0 <0.9.0: 0.7.0到0.9.0之间(不包括0.9.0)


2、导入语句

// 相对路径导入
import "../utils/Helpers.sol";

// 绝对路径导入(取决于项目配置)
import "/project/contracts/Token.sol";

// 从 OpenZeppelin 合约导入
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

// 从其他安装的包导入
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";

// 从 URL 导入
import "

// 部分导入
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

用于引入其他合约文件或库

支持相对路径和通过 npm 安装的包(如 OpenZeppelin 合约、chainlink合约)


3. 合约主体结构

  • 状态变量

contract MyContract {
    // 公开状态变量(自动生成getter函数)
    uint256 public count;
    
    // 私有状态变量
    address private owner;
    
    // 常量
    uint256 constant MAX_SUPPLY = 1000;
    
    // 不可变变量(只能在构造函数赋值)
    uint256 immutable creationTime;
}
  • 结构体和枚举

// 结构体定义
struct User {
    string name;
    uint256 balance;
    bool isActive;
}

// 枚举类型
enum Status { Active, Inactive, Suspended }
  • 事件定义

event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
  • 修饰符

modifier onlyOwner() {
    require(msg.sender == owner, "Not owner");
    _;
}
  • 构造函数

constructor(uint256 initialCount) {
    count = initialCount;
    owner = msg.sender;
    creationTime = block.timestamp;
}
  • 函数定义

// 普通函数
function increment() public {
    count += 1;
}
// 带修饰符的函数
function reset() public onlyOwner {
    count = 0;
}
// view函数(只读)
function getCount() public view returns (uint256) {
    return count;
}
// pure函数(不访问状态)
function add(uint256 a, uint256 b) public pure returns (uint256) {
    return a + b;
}
// payable函数(可接收ETH)
function deposit() public payable {
    // 处理逻辑
}


4、完整合约示例

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";
contract Counter is Ownable {
    uint256 public count;
    uint256 immutable maxCount;
    
    event CountChanged(uint256 newCount);
    
    constructor(uint256 _maxCount) {
        maxCount = _maxCount;
    }
    
    modifier belowMax() {
        require(count < maxCount, "Reached maximum");
        _;
    }
    
    function increment() public belowMax {
        count += 1;
        emit CountChanged(count);
    }
    
    function reset() public onlyOwner {
        count = 0;
        emit CountChanged(0);
    }
    
    function getMax() public view returns (uint256) {
        return maxCount;
    }
}


5、代码结构最佳实践

  • 布局顺序:通常按照版本声明 → 导入 → 合约 → 状态变量 → 事件 → 修饰符 → 函数 的顺序组织

  • 可见性:明确指定函数和变量的可见性(public/private/internal/external)

  • 注释规范:使用 NatSpec 格式注释

  • 模块化:将复杂逻辑拆分为多个合约或库

  • 安全考虑:使用检查-效果-交互(CEI)模式