当前位置: 首页 > news >正文

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 费用不会退还。
// 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),提示用户。
http://www.xdnf.cn/news/1106065.html

相关文章:

  • 【Luogu】每日一题——Day1. P3385 【模板】负环
  • 上位机知识篇---高效下载安装方法
  • Script Error产生的原因及解法
  • 机器学习详解
  • Day58
  • Java基础-String常用的方法
  • 隆重介绍 Xget for Chrome:您的终极下载加速器
  • Linux入门篇学习——Linux 编写第一个自己的命令,make 工具和 makefile 文件
  • 嵌入式八股文之 GPIO
  • 鸿蒙系统安全机制全解:安全启动 + 沙箱 + 动态权限实战落地指南
  • 【驱动】移植CH340驱动,设置 udev 规则,解决和 BRLTTY 的冲突
  • Word表格默认格式修改成三线表,一劳永逸,提高生产力!
  • FREERTOS根本不能使用连续接收串口思想
  • P4597 序列 sequence题解
  • 跟着Carl学算法--二叉树【3】
  • 猿人学js逆向比赛第一届第十九题
  • 【每日算法】专题八_分治_归并排序
  • RLHF:人类反馈强化学习 | 对齐AI与人类价值观的核心引擎
  • Windows解决 ping 127.0.0.1 一般故障问题
  • 阿里云服务器,CentOS7.9上安装YApi 接口管理平台
  • Redis概念和基础
  • AI基建还能投多久?高盛:2-3年不是问题,回报窗口才刚开启
  • 学习C++、QT---21(QT中QFile库的QFile读取文件、写入文件的讲解)
  • MySQL内置函数(8)
  • Windows删除文件或者拔出U盘显示正在使用/占用解决办法
  • 必备软件推荐:1、Everything:Windows 文件查找的终极利器
  • CSS和CSS3区别对比
  • [面试] 手写题-插入排序
  • 网络安全第一次作业
  • 史上最详细Java并发多线程(面试必备,一篇足矣)