本文最后更新于 2024-04-26,本文发布时间距今超过 90 天, 文章内容可能已经过时。最新内容请以官方内容为准

Solidity 关键字差异与使用指南 📘

Static Badge

在 Solidity 中,有几个关键字在日常使用中容易混淆,它们各自有不同的用途和特性。

Immutable vs Constant 🛠️

Immutable 🔒

immutable是 Solidity 0.8.0 版本引入的一个关键字,用于定义一个在构造函数中只能被赋值一次的变量。一旦赋值,它的值就不能被再次修改。

pragma solidity ^0.8.0;

contract MyContract {
    address public immutable owner;
    uint public immutable maxSupply;

    constructor() {
        owner = msg.sender;
        maxSupply = 1000;
    }
}

Constant #️⃣

constant用于定义一个在编译时就已经确定,并且在运行时不可变的变量。它们通常用于存储那些永远不需要改变的值。

pragma solidity ^0.8.0;

contract MyContract {
    uint public constant MAX_SUPPLY = 1000;
}

关键差异 🔍

  • 赋值时间: immutable在合约构造时赋值,而constant在编译时赋值。
  • 可变性: immutable在构造后不可变,constant完全不可变。
  • 用途: immutable用于设置只需要初始化一次的值,constant用于存储硬编码值。

使用场景 🎭

  • 使用immutable当你需要在合约构造时设置一个值,并且这个值之后不应该改变。
  • 使用constant当你需要存储一个永远不会改变的硬编码值。

View vs Pure 🔬

View 👀

view关键字用于声明一个函数,该函数不会修改合约的任何状态,即不会产生状态变量的变更。

pragma solidity ^0.8.0;

contract MyContract {
    uint private _balance;

    function getBalance() public view returns (uint) {
        return _balance;
    }
}

Pure 💧

pure关键字用于声明一个函数,它不仅不会修改合约状态,也不会读取合约的状态。

pragma solidity ^0.8.0;

contract MyContract {
    function add(uint a, uint b) public pure returns (uint) {
        return a + b;
    }
}

关键差异 🔍

  • 状态修改: view可以读取状态变量,但不能修改,pure既不能读取也不能修改状态变量。
  • 交易: view函数不产生交易,因为它们不修改区块链状态。
  • 用途: view用于提供关于合约当前状态的信息,pure用于执行不依赖于合约状态的计算。

使用场景 🎭

  • 使用view当你需要提供一个只读的接口来获取合约的状态信息。
  • 使用pure当你需要执行不依赖于合约状态的计算。

Public vs Private vs Internal vs External 🏠

Public 🌐

public关键字用于声明一个函数或变量,它可以被合约外部访问,并且可以通过合约的名称直接访问。

pragma solidity ^0.8.0;

contract MyContract {
    uint public totalSupply;
}

Private 🔑

private关键字用于声明只能在同一个文件内访问的变量或函数。

pragma solidity ^0.8.0;

contract MyContract {
    uint private _totalSupply;
}

Internal 📂

internal关键字用于声明一个函数或变量,它只能在当前合约和它的派生合约中访问。

pragma solidity ^0.8.0;

contract MyContract {
    function _internalFunction() internal {
        // ...
    }
}

External 🚪

external关键字用于声明函数,表示该函数只能被合约外部调用,不能被合约内部的其他函数调用。这通常用于表示那些需要从外部世界接收消息的函数。

pragma solidity ^0.8.0;

contract MyContract {
    function externalFunction() external {
        // 这个函数只能从合约外部调用
    }
}

关键差异 🔍

  • 可访问性: public对外部完全开放,private仅限于当前文件,internal限于当前合约及其派生合约。
  • 外部交互: 只有public函数和状态变量可以通过合约外部直接交互。
  • Public: 完全公开,可以被外部调用,也可以被合约内部调用。状态变量如果声明为public,相当于提供了一个公共接口。
  • Private: 只能在当前文件内访问,对于外部和派生合约都不可见。
  • External: 只能从合约外部调用,不能从合约内部调用。通常用于合约间的交互。
  • Internal: 只能在当前合约内部访问,对于外部和派生合约都不可见。

使用场景 🎭

  • 使用public: 当你需要提供一个可以被外部直接访问的接口。
  • 使用private: 当你需要隐藏实现细节,只允许当前合约内部访问。
  • 使用internal: 当你需要在当前合约及其派生合约中共享功能,但不暴露给外部。
  • 使用External: 当你需要定义一个函数,这个函数仅供合约外部调用,以实现特定的交互逻辑时。

理解这些关键字的细微差别对于编写结构良好、可维护的智能合约至关重要。正确使用它们可以提高合约的安全性和灵活性。🔐🛠️📜