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

For and While Loop

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

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

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

For and While Loop

Solidity 支持 for、while 和 do while 循环。

不要编写无界循环(无限循环),因为这可能会达到 Gas 限制,导致交易失败。

由于上述原因,while 和 do while 循环很少使用。

  • 循环支持:
    • Solidity 提供三种循环结构:
      • for 循环:适合已知迭代次数的场景。
      • while 循环:适合条件驱动的循环。
      • do while 循环:类似 while 循环,但至少执行一次(本例中未展示)。
    • 这些循环与传统编程语言(如 C++、JavaScript)中的循环类似,用于重复执行代码块。
  • 无界循环的危险:
    • 无界循环(例如无限循环或迭代次数过大的循环)可能耗尽交易的 Gas 限制(Gas Limit),导致交易失败。
    • 失败的交易会回滚状态变更,但已消耗的 Gas 费用不会退还。
    • 因此,Solidity 开发者需要谨慎设计循环,确保迭代次数可控。
  • while 和 do while 循环的稀少使用:
    • 由于难以预测循环次数,whiledo while 循环可能导致 Gas 超支,因此在智能合约中较少使用。
    • for 循环更常见,因为可以通过初始化、条件和步进来控制迭代次数。
// 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 Loop {// 定义一个名为 `Loop` 的智能合约。// 合约是一个运行在以太坊区块链上的程序,包含数据(状态变量)和逻辑(函数)。// 这个合约的目的是展示 Solidity 中的 for 和 while 循环,以及循环控制语句(continue 和 break)。function loop() public pure {// 定义一个名为 `loop` 的公共函数。// `public` 表示函数可以被外部调用(用户、其他合约或 DApp)。// `pure` 表示函数不读取也不修改区块链状态(仅进行计算),链下调用不消耗 Gas。// 没有返回值(隐式返回 `void`)。// for loop// for 循环for (uint256 i = 0; i < 10; i++) {// 定义一个 for 循环,包含三部分:// 1. 初始化:`uint256 i = 0` - 创建循环变量 `i`,初始值为 0,类型为 `uint256`(无符号整数)。// 2. 条件:`i < 10` - 循环继续的条件是 `i` 小于 10。// 3. 步进:`i++` - 每次循环后,`i` 增加 1。// 循环体将执行 10 次(i = 0, 1, 2, ..., 9)。if (i == 3) {// 如果 `i` 等于 3,执行以下代码块。// Skip to next iteration with continue// 使用 continue 跳到下一次迭代continue;// `continue` 语句跳过当前循环的剩余代码,直接进入下一次迭代。// 当 `i == 3` 时,循环跳过后续代码(不执行 `if (i == 5)` 的检查),`i` 增加到 4。}if (i == 5) {// 如果 `i` 等于 5,执行以下代码块。// Exit loop with break// 使用 break 退出循环break;// `break` 语句立即终止整个循环。// 当 `i == 5` 时,循环结束,不再执行后续迭代。}}// while loop// while 循环uint256 j;// 声明一个变量 `j`,类型为 `uint256`,初始值为 0(未显式初始化,Solidity 默认赋值为 0)。// 变量 `j` 是函数的局部变量,存储在内存中,不占用区块链存储。while (j < 10) {// 定义一个 while 循环,条件为 `j < 10`。// 只要 `j` 小于 10,循环体就会继续执行。j++;// 将 `j` 增加 1。// 循环将执行 10 次(j = 0, 1, 2, ..., 9),直到 `j` 达到 10,条件不再满足。}}
}

Loop 是一个简单的智能合约,展示了 Solidity 中的 for 循环while 循环,以及循环控制语句 continuebreak 的使用。

代码做什么

  • for 循环:
    • 迭代 10 次(i 从 0 到 9)。
    • i == 3 时,使用 continue 跳过当前迭代(不执行后续代码,直接进入下一次迭代)。
    • i == 5 时,使用 break 提前退出循环(不再迭代 i = 6, 7, 8, 9)。
    • 实际执行的迭代是:i = 0, 1, 2, 4(跳过 3,终止于 5)。
  • while 循环:
    • 迭代 10 次(j 从 0 到 9),每次将 j 加 1。
    • j 达到 10,循环条件 j < 10 不满足,循环结束。
  • Gas 成本:
    • 函数是 pure,不修改区块链状态,链下调用不消耗 Gas。
    • 如果循环涉及状态变量修改(例如 i 是状态变量),每次迭代会消耗 Gas。
  • 无界循环警告:
    • 代码中的循环是有限的(10 次迭代),但如果写成无界循环(例如 while (true)),可能耗尽 Gas,导致交易失败。

用途

  • 循环在智能合约中用于:
    • 处理数组或列表(例如,遍历用户列表)。
    • 执行重复操作(例如,批量转账)。
    • 实现复杂逻辑(例如,计算总和或查找特定条件)。
  • 必须确保循环次数有限,避免 Gas 超支。

关键点:

  • for 循环:

    • 适合已知迭代次数的场景(例如,遍历固定长度的数组)。
    • 包含初始化、条件和步进,确保循环可控。
    • 使用 continue 跳过特定迭代,break 提前退出循环。
  • while 循环:

    • 适合未知迭代次数但有明确退出条件的场景。
    • 需要手动更新循环变量(例如 j++),否则可能变成无界循环。
    • 在智能合约中较少使用,因为难以预测 Gas 消耗。
  • do while 循环:

    • 本例未展示,但格式为:

      do {// 代码块
      } while (条件);
      
    • 至少执行一次,即使条件初始不满足。

    • 同样需避免无界循环。

  • Gas 优化:

    • 循环中的每次操作(例如计算、状态修改)都消耗 Gas。
    • 无界循环或过多迭代可能导致交易失败,需设置合理的循环次数。
    • pure 函数不消耗 Gas,但如果循环修改状态变量,需估算 Gas 成本。
  • 安全性:

    • 确保循环有明确的退出条件,避免无限循环。
    • 在循环中处理外部调用(如转账)需谨慎,可能导致 Gas 攻击或重入漏洞。

循环的注意事项

  • 避免无界循环:
    • 无界循环(例如 while (true))可能耗尽 Gas,导致交易失败。
    • 始终设置明确的退出条件或最大迭代次数。
  • Gas 消耗:
    • 循环中的状态修改(例如更新状态变量)每次迭代消耗 Gas。
    • 使用 pureview 函数可避免 Gas 成本,但实际应用中常需修改状态。
  • 循环控制:
    • continue:跳过当前迭代,进入下一次。
    • break:提前退出循环,节省 Gas。
  • 安全性:
    • 避免在循环中调用外部合约(可能导致 Gas 攻击或重入漏洞)。
    • 检查数组长度或其他条件,防止越界访问。
  • while vs. for:
    • for 适合已知迭代次数,结构清晰。
    • while 适合动态条件,但需确保退出条件明确。
    • do while 至少执行一次,适合特殊场景,但使用较少。

文章转载自:
http://captress.kjawz.cn
http://childish.kjawz.cn
http://abortarium.kjawz.cn
http://amnion.kjawz.cn
http://bionic.kjawz.cn
http://bactericidal.kjawz.cn
http://bircher.kjawz.cn
http://biopotency.kjawz.cn
http://apocalypse.kjawz.cn
http://anatomise.kjawz.cn
http://bark.kjawz.cn
http://antichristianism.kjawz.cn
http://adversely.kjawz.cn
http://basidiospore.kjawz.cn
http://bravissimo.kjawz.cn
http://buffo.kjawz.cn
http://caodaist.kjawz.cn
http://airdrop.kjawz.cn
http://calcicole.kjawz.cn
http://aluminosilicate.kjawz.cn
http://agronomics.kjawz.cn
http://brassart.kjawz.cn
http://chicken.kjawz.cn
http://apostate.kjawz.cn
http://anvers.kjawz.cn
http://boche.kjawz.cn
http://afterpains.kjawz.cn
http://cabby.kjawz.cn
http://aldehyde.kjawz.cn
http://career.kjawz.cn
http://www.dtcms.com/a/281540.html

相关文章:

  • javaScript 基础知识(解决80%js面试问题)
  • 代码随想录算法训练营十六天|二叉树part06
  • 配置nodejs,若依
  • 【08】MFC入门到精通——MFC模态对话框 和 非模态对话框 解析 及 实例演示
  • Git未检测到文件更改
  • 密码协议的基本概念
  • bytetrack漏检补齐
  • Nginx配置反向代理
  • 【世纪龙科技】智能网联汽车环境感知系统教学软件
  • C# StringBuilder源码分析
  • Java大厂面试实录:从Spring Boot到AI微服务架构的层层递进
  • 华为OD 特异双端队列
  • 魔搭官方教程【快速开始】-swift 微调报错:`if v not in ALL_PARALLEL_STYLES`
  • [数据结构]#3 循环链表/双向链表
  • Spring AI Alibaba 1.0 vs Spring AI 深度对比
  • 信息学奥赛一本通 1552:【例 1】点的距离
  • 记一次POST请求中URL中文参数乱码问题的解决方案
  • React响应式组件范式:从类组件到Hooks
  • Ubuntu 安装
  • 回收站里的文件被删除了怎么还原和恢复
  • 京存大容量存储助力“国漫之光”·玄机动画
  • 注解和反射
  • 3D视频技术全解析:从原理架构到产业应用的深度探索
  • Python文本统计分析工具
  • 集训Demo2
  • 巧用Bitset!优化dp
  • “C21988-谷物烘干机(2D+3D+说明书+运动仿真)8张cad+设计说明书
  • Eplan API SQL
  • 从灾前感知到灾后恢复:人工智能在城市气候风险管理中的全链路赋能
  • ESLint 除了在packages.json还能在哪里配置?