惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Recent Announcements
Recent Announcements
爱范儿
爱范儿
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
宝玉的分享
宝玉的分享
T
Tailwind CSS Blog
博客园_首页
IT之家
IT之家
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 三生石上(FineUI控件)
有赞技术团队
有赞技术团队
大猫的无限游戏
大猫的无限游戏
雷峰网
雷峰网
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 司徒正美
WordPress大学
WordPress大学
Last Week in AI
Last Week in AI
人人都是产品经理
人人都是产品经理
Jina AI
Jina AI
月光博客
月光博客
小众软件
小众软件
S
SegmentFault 最新的问题
量子位
阮一峰的网络日志
阮一峰的网络日志
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知

秋码分享

我是如何解决将 c++ 编译成可以在 node.js 中使用的 *.node,中间出现的一大堆问题的(指纹浏览器基石篇) eSIM Plus 爱沙尼亚手机号彻底翻车?“永久有效”悄然变成了一年! 接码平台 SMS-Activate 余额可以转移到新平台使用,截止日期:2026年1月29日 是时候将 hugo-theme-kiwi 主题提交到 themes.gohugo.io 站点上了 Flux2 刚开源就凉了?Z-Image 本地部署狠狠打了个样 声音的未来:Chatterbox —— 用「夸张度旋钮」提升表现力的开源 TTS 向导 还以为那只是换个背景?Qwen-Image-Edit 在 ComfyUI 中能做到更离谱的事 Windows 结合最新版 ComfyUI 部署阿里最新开源的 Qwen-Image 图像大模型 从零样本到跨场景:Seed-VC语音转换技术的革命性突破 大语音模型轻量化革命:MegaTTS3 如何重新定义文本生成语音的技术边界(windows篇) 竞赛级编程大模型OlympicCoder-7B之本地部署(Windows篇) 阿里开源了端到端全模态大模型Qwen-2.5-Omini-7B之本地部署(windows篇) 语音识别之whisper本地部署(实时语音之开篇) 甭管是个人还是企业都能部署的Mistral-Small3.1,远超同级别的模型 文生音乐开源项目DiffRhythm,8G显存本地部署之Windows篇 阿里QwQ-32B本地部署指南:用Ollama轻松运行320亿参数大模型 基于Qwen2.5大模型的Spark-TTS,零样本语音克隆,CPU可运行之本地部署(Windows篇) 智谱开源了文生图CogView4-6B模型,支持中文提示词之本地部署(Windows篇) 基于歌词生成整首歌的开源AI音乐模型,支持中、英、日、韩等多种语言,本地化部署YuE(windows篇) 阿里云开源的文生视频万相 Wan2.1之本地部署Wan2.1-T2V-1.3B模型 互动式开源AI图像编辑神器,Windows11本地部署 MagicQuill 本地部署Qwen2.5-VL-7B-Instruct多模态视觉大模型(Windows篇) 保持角色一致性的绘本生成AI开源项目之Story-Adapter本地部署Windows篇 本地部署 Stable Diffusion 3.5(最新 ComfyUI记录篇) 谁说Win7安装不了Node.js最新版的呢?都2025年,还不更新系统到Win11 vs code远程调试Linux服务器上的php代码 浏览器定制 | Windows11 编译 Chromium 133.0.6885.0(截稿前Chromium最新版之编译篇[一]) 不说是彻底搞懂,至少让你不再惧怕c/c++指针,以及各种奇葩指针变种 解决windows下php8.x及以上版本,在Apache2.4中无法加载CURL扩展的问题 在 Windows8.1 下编译 Chromium (103.0.5060.68 之三)
玩以太坊链上项目的必备技能(变量作用域-Solidity之旅五)
一个游离于山间之上的江湖漫行者。A jungle wanderer who wanders above the mountain · 2022-12-11 · via 秋码分享

局部变量(Local Variable)的范围仅限于它们被定义的函数,但 状态变量(State Variable) 可以有三种范围。 public - public 修饰的 状态变量(State Variable) 可以在内部以及通过消息进行访问,对于一个公共状态变量,会自动生成一个getter函数。

在前文我们讲过 Solidity 是一种静态类型的语言,这就意味着在声明变量前需先指定类型。

而 Solidity 对变量划分了以下三种作用域范围:

  • 状态变量(State Variable):

该变量的值被永久地存放在合约存储中,合约内所有函数可访问,其Gas(燃料)消耗高。

  • 局部变量(Local Variable):

函数体声明的变量,其值在该函数执行前都存在的变量。

  • 全局变量(Global Variable):

存在于全局命名空间的特殊变量,提供有关区块链和交易属性的信息。

状态变量(State Variable)

其值被永久地存放在一个合约存储中。

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract SolidityTest {
   uint storedData;      // 状态变量(State variable)
   //这是构造器函数
   constructor() public {
      storedData = 10;   // 使用 状态变量
   }
}

局部变量(Local Variable):

声明变量在函数体的变量,其值在函数执行前一直存在。

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

contract SolidityTest {
   uint storedData; // 状态变量
   //构造器函数
   constructor() public {
      storedData = 10;   
   }
   //声明一个函数
   function getResult() public view returns(uint){
      uint a = 1; // 局部变量(local variable)
      uint b = 2;
      uint result = a + b;
      return result; //返回 局部变量
   }
}

img

我们做些小改动,让函数返回 状态变量,会是什么样的结果呢?

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

contract SolidityTest {
   uint storedData; // 状态变量
   //构造器函数
   constructor() public {
      storedData = 10;   
   }
   //声明一个函数
   function getResult() public view returns(uint){
      uint a = 1; // 局部变量(local variable)
      uint b = 2;
      uint result = a + b;
      return storedData; //返回 状态变量
   }
}

img

您可能也注意到,编译图标下有 2 个警告。

img

img

针对第一个警告,那是 Solidity 0.7 版本之后对 构造器 的 可见修饰忽略了,解决办法:便是删除它。

而 第二个 警告 便是声明过的变量没有使用,这点倒是和 golang 很像,但在 Solidity 中并没有那么严格,只是给出警告提示,还是可以编译的,在这里建议,去掉没使用的变量。

全局变量(Global Variable)

存在全局工作区的特俗变量,用于提供区块链和交易的属性。

NameReturns
blockhash(uint blockNumber) returns (bytes32)Hash of the given block - only works for 256 most recent, excluding current, blocks
block.coinbase (address payable)Current block miner’s address
block.difficulty (uint)Current block difficulty
block.gaslimit (uint)Current block gaslimit
block.number (uint)Current block number
block.timestamp (uint)Current block timestamp as seconds since unix epoch
gasleft() returns (uint256)Remaining gas
msg.data (bytes calldata)Complete calldata
msg.sender (address payable)Sender of the message (current caller)
msg.sig (bytes4)First four bytes of the calldata (function identifier)
msg.value (uint)Number of wei sent with the message
now (uint)Current block timestamp
tx.gasprice (uint)Gas price of the transaction
tx.origin (address payable)Sender of the transaction
  • blockhash(uint blockNumber) returns (bytes32):指定区块的区块哈希 —— 仅可用于最新的 256 个区块且不包括当前区块,否则返回 0 。
  • block.basefee (uint): 当前区块的基础费用
  • block.chainid (uint): 当前链 id
  • block.coinbase ( address ): 挖出当前区块的矿工地址
  • block.difficulty ( uint ): 当前区块难度
  • block.gaslimit ( uint ): 当前区块 gas 限额
  • block.number ( uint ): 当前区块号
  • block.timestamp ( uint): 自 unix epoch 起始当前区块以秒计的时间戳
  • gasleft() returns (uint256) :剩余的 gas
  • msg.data ( bytes ): 完整的 calldata
  • msg.sender ( address ): 消息发送者(当前调用)
  • msg.sig ( bytes4 ): calldata 的前 4 字节(也就是函数标识符)
  • msg.value ( uint ): 随消息发送的 wei 的数量
  • tx.gasprice (uint): 交易的 gas 价格
  • tx.origin ( address ): 交易发起者(完全的调用链)

标识符

与众多编程语言一样,在您声明 Solidity 变量名称时,请不要使用 Solidity 保留关键字,如breakboolean变量名是无效的。

Solidity 标识符一样也是由字母下划线数字组成的,注意:不要以数字开头来命名变量名。

在 Solidity 中,标识符是区分大小写的,如:nameName是两个不同的变量名哦!

变量作用范围

局部变量(Local Variable)的范围仅限于它们被定义的函数,但 状态变量(State Variable) 可以有三种范围。

public - public 修饰的 状态变量(State Variable) 可以在内部以及通过消息进行访问,对于一个公共状态变量,会自动生成一个getter函数。

internal: internal(内部) 修饰的 状态变量(State Variable) 只能在内部从当前的合约或从它派生的合约中访问。

private:private 修饰的 状态变量(State Variable)只能从当前的合同内部访问,其派生类不能访问。

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

contract C {
   uint public data = 30;
   uint internal iData= 10;
   uint private pData = 5;

   function x() public returns (uint) {
      data = 3; // internal(内部)
      pData = 7;  //可以使用
      return data;
   }
}
contract Caller {
   C c = new C();
   function f() public view returns (uint) {
     //c.pData = 11;  报错  错误提示 变量不可见
      return c.data(); //external (外部)
   }
}
//合约 D 继承了合约 C  后续会讲到
contract D is C {
   function y() public returns (uint) {
      iData = 3; // internal (内部)
     // pData = 4;  报错 错误提示变量未定义
      return iData;
   }
   function getResult() public pure returns(uint){
      uint a = 1; // 局部变量(local variable)
      uint b = 2;
      uint result = a + b;
      return result; //状态变量(state variable)
   }
}

img