以太坊作为全球领先的区块链平台,其智能合约的实现离不开Solidity这一专门为智能合约设计的编程语言,掌握Solidity语法是进入以太坊开发世界的第一步,也是构建安全、可靠去中心化应用(DApps)的核心能力,本文将深入探讨Solidity的基础语法,助你踏上智能合约开发之旅。

Solidity简介与合约结构

Solidity是一种静态类型、面向合约的高级编程语言,语法风格类似JavaScript、Python和C++的结合体,它支持继承、库和复杂的用户定义类型等特性。

一个基本的Solidity合约由以下部分组成:

// SPDX-License-Identifier: MIT // 指定许可证标识符,推荐使用
pragma solidity ^0.8.0; // 指定编译器版本,^表示兼容0.8.0及以上,但低于0.9.0
// 合约定义
contract HelloWorld {
    // 状态变量(存储在区块链上)
    string public greeting;
    // 构造函数(在合约部署时执行一次)
    constructor(string memory _greeting) {
        greeting = _greeting;
    }
    // 函数(合约的行为)
    function setGreeting(string memory _newGreeting) public {
        greeting = _newGreeting;
    }
    function getGreeting() public view returns (string memory) {
        return greeting;
    }
}

核心语法元素

  1. 注释

    • 单行注释:// 这是注释
    • 多行注释:/* 这是多行注释 */
  2. 状态变量 存储在合约的存储中,状态变量的值会永久记录在区块链上。

    uint256 public myNumber; // 无符号整数,256位
    string public myString; // 字符串
    address public owner;   // 以太坊地址
    bool public isActive;   // 布尔值
  3. 数据类型

    • 值类型 (Value Types): 每个变量独立存储,包括:
      • bool: 布尔值 (true, false)
      • uint / int: 不同位宽的无符号/有符号整数 (如 uint8, uint256, int256)
      • address: 存储20字节的地址,有成员函数(如 balance, transfer
      • bytes1bytes32: 固定长度的字节数组
      • enum: 枚举类型
    • 引用类型 (Reference Types): 存储数据的引用,复杂类型,需要特别注意内存和存储位置:
      • arrays: 数组(固定大小或动态)
        uint256[] public dynamicArray; // 动态数组
        uint256[5] public fixedArray;  // 固定大小数组
      • struct: 自定义结构体
        struct Person {
            string name;
            uint age;
        }
        Person public person;
      • mapping: 键值对映射
        mapping(address => uint256) public balances; // 地址到余额的映射
  4. 修饰符 (Modifiers) 用于修改函数的行为,常用于输入验证或访问控制。

    modifier onlyOwner {
        require(msg.sender == owner, "Only owner can call this function");
        _; // 表示继续执行函数体
    }
    function withdraw() public onlyOwner {
        // 函数体
    }
  5. 函数 (Functions) 合约的核心,定义了业务逻辑和交互方式。

    • 可见性修饰符:
      • public: 内部和外部均可访问,自动生成getter函数。
      • private: 只在当前合约内部可访问。
      • internal: 只在当前合约及继承它的合约中可访问。
      • external: 只能从合约外部调用,内部调用需要使用this.f()
    • 状态可变性修饰符:
      • view: 函数读取状态但不修改,不消耗gas(除了在合约内部调用时)。
      • pure: 函数既不读取也不修改状态,不消耗gas。
      • constant: view的旧版别名,已不推荐使用。
      • 默认(无修饰符):函数会修改状态,消耗gas。
    • 函数修饰符: 可以组合使用,如 public view onlyOwner
    • 返回值: 使用 returns (type1 name1, type2 name2) 声明。
      function add(uint256 a, uint256 b) public pure returns (uint256) {
      return a + b;
      }
  6. 特殊变量和函数

    • msg.sender: 调用函数的地址。
    • msg.value: 发送的以太币数量(以wei为单位)。
    • msg.data: 调用函数时包含完整调用数据的calldata。
    • address(this: 合约本身的地址。
    • require(condition, "error message"): 用于条件检查,失败时回滚状态变更并停止执行。
    • assert(condition): 用于内部错误检查,失败时抛出panic错误(严重错误,通常表示bug)。
    • 随机配图