玩以太坊链上项目的必备技能(变量作用域-Solidity之旅五)

news2024/11/19 23:44:53

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

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

  • 状态变量(State Variable):

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

  • 局部变量(Local Variable):

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

  • 全局变量(Global Variable):

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

状态变量(State Variable)

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

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; //返回 局部变量
   }
}

在这里插入图片描述

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

// 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; //返回 状态变量
   }
}

在这里插入图片描述

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

在这里插入图片描述

在这里插入图片描述

针对第一个警告,那是 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)
   }
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/80686.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JS新年倒计时

✅作者简介:热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏:前端案例分…

Java---线程详解

目录 一、线程的介绍 二、线程的使用 (1)多线程的实现 1:继承Thread类 2:实现Runnable接口 (2)设置和获取线程名称 1:继承Thread类 2:实现Runnable接口 (3)线程…

Java学习—多线程Thread

多线程1. 线程简介1.1 普通方法和多线程1.2 程序、进程、线程2. 线程创建2.1 Thread类案例:下载图片2.2 Runnable接口案例:龟兔赛跑2.3 Callable接口3. 静态代理4. Lamda表达式5. 线程状态5.1 线程方法5.2 停止线程5.3 线程休眠5.4 线程礼让-yield5.5 Jo…

揭秘SpringMVC-DispatcherServlet之九大组件(二)

前言 上回聊到了HandlerAdapter,今天继续聊后面的组件。今天的主角是HandlerMapping,这篇文章全为他服务了。 HandlerMapping 上回说的Handler,我们说是处理特定请求的。也就是说,不是所有的请求都能处理。那么问题来了&#x…

gateway初始化与配置

1、排除依赖 spring-boot-starter-webflux 2、添加依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <dependency><groupId>org.springf…

基于GDAL的JAVA生成GDB文件实战

前言 在之前博客中&#xff0c;陆续的介绍了关于gdb文件的读取&#xff0c;gis利器之Gdal&#xff08;三&#xff09;gdb数据读取&#xff0c;玩转GDAL一文带你深入Windows下FileGDB驱动支持&#xff0c;这些文章主要都是介绍gdal的读取gdb以及简单的gdb文件读写。在实际工作中…

VJ个人周赛

A:模拟 题意&#xff1a;给定了N个任务&#xff0c;每个任务都有一个优先级&#xff08;1~9&#xff09;&#xff0c;数字越大&#xff0c;优先级越高。将这些任务放入队列中&#xff0c;如果出队的元素&#xff08;x&#xff09;&#xff0c;x的优先级不是最高的&#xff0c;那…

从高级测试到测试开发有什么感悟

最近加入了新的团队&#xff0c;角色发生较大的转变&#xff0c;在这里分享一下自己的感受。 测试的划分 如果我们把产品的生产看成一个流水线的话&#xff0c;那么测试就是流水线上的一个重要岗位&#xff0c;把控着产品的质量。 当然&#xff0c;产品类型的不同&#xff0…

信息系统安全管理

信息系统安全是一个绕不开的话题。从事IT行业&#xff0c;不论何种角色&#xff0c;哪个工种&#xff0c;都需要有所了解。 一、信息系统安全策略 1、概述 信息系统安全策略是指对&#xff08;本单位&#xff09;信息系统的安全风险&#xff08;安全威胁&#xff09;进行有效…

小白学编程(js):通过按钮变换背景颜色

《JavaScript从入门到精通》【例9.1】 代码演示&#xff1a; <body><form class"form1" action"" name"form1" method"psot"><p><input type"button" name"Submit" value"变换背景&qu…

[附源码]计算机毕业设计基于Java的图书购物商城Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Linux常用环境配置及软件安装(持续更新)

1、jdk 1、下载jdk Linux安装包 把安装包放到自己定义的目录下 安装包网盘 提取码&#xff1a;n5hj 2、解压 解压安装包&#xff0c;输入命令&#xff1a; tar -xvf jdk-8u221-linux-x64.tar.gz 解压完成后会生成一个新文件 3、配置环境变量 编辑profile文件 vim /etc/p…

基于java+springboot+mybatis+vue+mysql的高校党务系统

项目介绍 本党务管理系统主要包括五大功能模块&#xff0c;即管理员模块、学生模块、积极分子模块、党员、党建组织。 &#xff08;1&#xff09;管理员模块&#xff1a;主要功能有&#xff1a;首页、个人中心、学生管理、学院管理、专业管理、班级管理、积极分子管理、党员管…

LeetCode HOT 100 —— 208. 实现 Trie (前缀树)

题目 Trie&#xff08;发音类似 “try”&#xff09;或者说 前缀树 是一种树形数据结构&#xff0c;用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景&#xff0c;例如自动补完和拼写检查。 请你实现 Trie类&#xff1a; Trie() 初始化前缀树对象。 vo…

postgresql_internals学习笔记(二)常规vacuum

一、 作用与原理 page pruning执行速度很快&#xff0c;但它们的作用范围毕竟只有单页、且不包含索引&#xff0c;因此&#xff0c;我们还需要更有效的清理机制。 常规vacuum是最常用的一种&#xff0c;作用范围可以是整张表&#xff0c;清理过期元组及索引项&#xff0c;并且不…

PS图层+移动工具(1)图层概念-拖动操作-移动工具基础

先打开ps软件 然后点击进入工作区 选择右上角文件 点击打开 随便选一个要操作的图片 然后看一下自己工作区右侧的 这个图层工具开了没有 如果没开 点击上方 窗口 将图层选项勾选上 这里可以看到 我们打开一个完整图片 他就只有一个图层 触发你打开的是PSD格式的图片 psd是ps…

【云计算与大数据技术】云交付模型、云部署模型、云计算优势与挑战、应用的讲解(超详细必看)

一、云交付模型 云计算主要分为三种交付模型&#xff0c;而且这三种交付模型主要是从用户体验的角度出发的&#xff0c;分别是软件即服务&#xff08;SaaS&#xff09;&#xff0c;平台即服务&#xff08;PaaS&#xff09;&#xff0c;基础设施即服务&#xff08;IaaS&#xf…

数据库建表的 15 个最佳实践方式

前言 对于后端开发同学来说&#xff0c;访问数据库&#xff0c;是代码中必不可少的一个环节。 系统中收集到用户的核心数据&#xff0c;为了安全性&#xff0c;我们一般会存储到数据库&#xff0c;比如&#xff1a;mysql&#xff0c;oracle等。 后端开发的日常工作&#xff…

string的模拟实现

目录 ​一、模拟实现中类的组织 二、默认成员函数 1.默认构造函数 2.拷贝构造函数 &#xff08;1&#xff09;传统写法——循规蹈矩 &#xff08;2&#xff09;现代写法——偷天换日 3.析构函数 4.赋值运算符重载 二、元素访问 三、容量操作 1.容量与有效数据 2.改…

SpringBootStarter技术:生产就绪与环境配置、实现自定义Starter

● Spring 官 方 Starter &#xff1a; 命 名 应 遵 循 spring-boot-starter-{name} 的 格 式 &#xff0c; 如 spring-boot-starter-web 作 为 SpringBoot Web模块的官方artifactId。 ● Spring 非 官 方 Starter &#xff1a; 命 名 应 遵 循 {name}-spring-bootstarter的格…