Gas and Gas Price

本节是《Solidity by Example》的中文翻译与深入讲解,专为零基础或刚接触区块链开发的小白朋友打造。我们将通过"示例 + 解说 + 提示"的方式,带你逐步理解每一段 Solidity 代码的实际用途与背后的逻辑。

Solidity 是以太坊等智能合约平台使用的主要编程语言,就像写网页要用 HTML 和 JavaScript,写智能合约就需要会 Solidity。

如果你从没写过区块链代码也没关系,只要你了解一点点编程概念,比如"变量""函数""条件判断",我们就能从最简单的例子开始,一步步建立你的 Solidity 编程思维。

Gas and Gas Price

Gas

执行一笔交易需要支付多少以太(Ether)?

你需要支付的以太 = 消耗的 Gas 数量 * Gas 价格,其中:

  • Gas 是计算的单位
  • 消耗的 Gas 是交易中使用的 Gas 总量
  • Gas 价格是你愿意为每单位 Gas 支付的以太数量
    Gas 价格更高的交易有更高的优先级被包含在区块中

未使用的 Gas 将被退还。

Gas Limit

Gas 消耗有两个上限:

  • Gas 限制(你愿意为交易使用的最大 Gas 数量,由你设置)
  • 区块 Gas 限制(一个区块允许的最大 Gas 数量,由网络设置)

描述解释:

  • 什么是 Gas?
    • Gas 是以太坊网络中用于衡量计算工作量的单位。每次执行交易(如调用合约函数、转账)都需要消耗一定量的 Gas。
    • 类似于"油费",Gas 是运行区块链操作的"燃料"。
  • 交易费用计算:
    • 交易费用 = 消耗的 Gas 数量(Gas Spent) × Gas 价格(Gas Price)
    • Gas 数量:取决于交易的复杂程度(例如,存储数据比简单计算更耗 Gas)。
    • Gas 价格:用户设置的每单位 Gas 愿意支付的以太(以 Wei 或 Gwei 为单位,例如 20 Gwei)。
    • 更高的 Gas 价格会激励矿工(或验证者)优先处理你的交易。
  • 未使用的 Gas:
    • 如果交易设置的 Gas 限制(Gas Limit)高于实际消耗的 Gas,多余的 Gas 会退还给用户。
    • 例如:设置 Gas 限制为 100,000,但实际只用了 50,000,则 50,000 Gas 的费用会退还。
  • Gas 限制(Gas Limit):
    • 交易 Gas 限制:由用户设置,表示愿意为单笔交易支付的最大 Gas 数量。
      • 太低可能导致交易失败(Gas 不够完成操作)。
      • 太高可能浪费 Ether(虽然未使用的 Gas 会退还)。
    • 区块 Gas 限制:由以太坊网络设置,表示一个区块能包含的所有交易的 Gas 总量上限。
      • 确保区块不会过大,影响网络性能。
  • 交易失败:
    • 如果交易耗尽了 Gas 限制(例如进入无限循环),交易会失败,状态变更会被回滚,但已消耗的 Gas 费用不会退还。
javascript 复制代码
// SPDX-License-Identifier: MIT
// 声明代码采用 MIT 开源许可证,允许自由使用、修改和分发代码。

pragma solidity ^0.8.26;
// 指定 Solidity 编译器版本必须大于或等于 0.8.26 并且小于 0.9.0。
// `pragma` 指令确保合约使用兼容的编译器版本,`^0.8.26` 表示支持 0.8.26 或更高版本(但不超过 0.9.0)。

contract Gas {
    // 定义一个名为 `Gas` 的智能合约。
    // 合约是一个运行在以太坊区块链上的程序,包含数据(状态变量)和逻辑(函数)。
    // 这个合约的目的是展示 Gas 消耗的行为,特别是当 Gas 用尽时会发生什么。

    uint256 public i = 0;
    // 声明一个名为 `i` 的状态变量,类型为 `uint256`(256 位无符号整数,范围从 0 到 2^256-1)。
    // 初始化值为 0,存储在区块链上。
    // `public` 关键字表示该变量可以被外部访问,Solidity 会自动为其生成一个 getter 函数(类似于 `function i() public view returns (uint256)`)。

    // Using up all of the gas that you send causes your transaction to fail.
    // State changes are undone.
    // Gas spent is not refunded.
    // 如果用尽了你发送的所有 Gas,交易会失败。
    // 状态变更会被撤销。
    // 已消耗的 Gas 不会退还。
    function forever() public {
        // 定义一个名为 `forever` 的公共函数。
        // `public` 表示函数可以被外部调用(用户、其他合约或 DApp)。
        // 没有 `view` 或 `pure` 修饰符,表示函数会修改区块链状态,需消耗 Gas。

        // Here we run a loop until all of the gas are spent
        // and the transaction fails
        // 这里运行一个循环,直到所有 Gas 耗尽,导致交易失败。
        while (true) {
            // 无限循环(`true` 表示循环条件永远成立)。
            i += 1;
            // 每次循环将状态变量 `i` 的值增加 1。
            // 修改状态变量需要 Gas(因为更新区块链存储)。
            // 由于是无限循环,函数会持续消耗 Gas,直到达到交易的 Gas 限制(Gas Limit)。
            // 当 Gas 用尽时,交易失败,`i` 的变更被撤销(回滚),但已消耗的 Gas 不退还。
        }
    }
}

Gas 是一个简单的智能合约,展示了以太坊中 Gas 的消耗行为,特别是当交易耗尽 Gas 时的后果。

代码做什么?

  • 状态变量 i
    • 存储一个数字,初始值为 0,永久保存在区块链上。
    • 因为是 public,可以通过 getter 函数(i())读取。
  • 函数 forever
    • 运行一个无限循环,每次循环将 i 加 1。
    • 每次循环修改 i 会消耗 Gas(因为更新区块链状态)。
    • 由于循环永不停止,函数会一直消耗 Gas,直到达到用户设置的 Gas 限制(Gas Limit)
    • 当 Gas 用尽:
      • 交易失败。
      • i 的任何变更(例如增加到某个值)会被撤销(回滚到 0)。
      • 已消耗的 Gas 费用不会退还。
  • Gas 消耗演示:
    • 部署合约需要 Gas(初始化 i)。
    • 调用 forever 会消耗大量 Gas,直到失败。
    • 调用 i 的 getter 函数是 view 操作,链下调用免费。

关键点:

  • Gas 的作用:
    • Gas 限制了交易的计算量,防止无限循环或恶意代码耗尽网络资源。
    • 每种操作(例如计算、存储、调用)都有固定的 Gas 成本。
  • 交易失败:
    • 如果 Gas 用尽(例如 forever 的无限循环),交易失败,状态变更回滚。
    • 已消耗的 Gas 不会退还,因为矿工已经为计算付出了工作。
  • Gas 限制:
    • 交易 Gas 限制 :用户设置,例如 100,000 Gas。如果 forever 耗尽这 100,000 Gas,交易失败。
    • 区块 Gas 限制:网络设置,例如 30,000,000 Gas,限制一个区块的总 Gas 消耗。
  • Gas 价格:
    • 用户设置 Gas 价格(例如 20 Gwei),决定交易优先级。
    • 总费用 = Gas 消耗 × Gas 价格(以 Wei 计算)。
  • 用途:
    • 理解 Gas 对于编写高效、安全的智能合约至关重要。
    • 开发者需要优化代码,减少 Gas 消耗(例如避免无限循环)。

Gas 的注意事项

  • Gas 耗尽:
    • 如果交易耗尽 Gas(例如 forever 的无限循环),交易失败,状态回滚,已用 Gas 不退还。
    • 确保设置合理的 Gas 限制,覆盖预期操作。
  • Gas 优化:
    • 避免无限循环或复杂计算。
    • 使用 immutableconstant 变量减少存储成本。
    • 合并状态更新,减少写入次数。
  • Gas 价格:
    • Gas 价格过低可能导致交易长时间未被打包(特别是在网络拥堵时)。
    • 使用 Gas 价格推荐工具(如 Etherscan Gas Tracker)设置合理价格。
  • 安全性:
    • 在处理 Ether 时,检查 msg.value 和 Gas 限制,防止意外失败。
    • 避免在循环中调用外部合约(可能导致 Gas 攻击)。
  • 实际应用:
    • 转账:确保 Gas 足够覆盖转账操作。
    • 合约调用:估算复杂函数的 Gas 消耗,设置适当的 Gas 限制。
    • 前端交互:在 DApp 中显示 Gas 费用(以 Ether 或 Gwei),提示用户。
相关推荐
电报号dapp11912 小时前
治理代币的质押周期应该如何科学设定?
人工智能·web3·去中心化·区块链·智能合约
Web3_Daisy16 小时前
想要抢早期筹码?FourMeme专区批量交易教学
大数据·人工智能·区块链·比特币
MetaverseMan16 小时前
以太坊重放攻击
区块链
MicroTech20251 天前
微算法科技基于格密码的量子加密技术,融入LSQb算法的信息隐藏与传输过程中,实现抗量子攻击策略强化
区块链·量子计算
SCIS5882 天前
深入理解区块链 | 去中心化架构与密码学保障
区块链·密码学·数据安全
全栈还没全2 天前
什么是Gas?使用场景以及开发中如何不使用Gas进行开发
区块链
代码羊羊3 天前
Foundry 依赖库管理实战
区块链·foundry
boyedu3 天前
以太坊智能合约核心技术解析与应用实践
区块链·智能合约
穗余3 天前
Solidity——什么是状态变量
区块链