solidity基础 -- 可视范围

news/2025/1/31 14:41:14/

        在 Solidity 编程语言中,可视范围(Visibility)用于控制合约中变量和函数的访问权限。这对于确保合约的安全性、模块化以及代码的可维护性至关重要。Solidity 提供了四种可视范围修饰符:publicprivateexternal 和 internal。以下将结合给定代码进行详细介绍。

        注意:使用继承时请确保代码的正确性,以防丢失个人财产,在这里友情提示您,不要复制来源不明的solidity代码并进行部署。本文为自己梳理总结,如有不足还请指出,感谢包容。

        学习更多solidity知识请访问 Github -- solidity基础 ,更多实例在 Smart contract

  • public:外部和内部可见(为 storage/state 变量创建 getter 函数)

    private:仅在当前合同中可见

    external:仅在外部可见(仅适用于函数)- 即只能通过消息调用(通过this.func)

    internal:仅在内部可见,合约内部进行调用

 

1. public 可视范围

  • 定义:具有 public 可视范围的变量或函数在合约内部和外部都可见。对于状态变量(storage 变量),Solidity 会自动为其创建一个 getter 函数,使得外部合约或用户可以通过该 getter 函数访问该变量的值。
  • 实例:在 VisibilityBase 合约中,uint public z = 2; 声明了一个 public 状态变量 z。外部合约或用户可以通过调用 getter 函数(例如 contractInstance.z())来获取 z 的值。同时,在合约内部,其他函数也可以直接访问 z。例如:
function accessZ() public view returns (uint) {return z;
}

 

2. private 可视范围

  • 定义private 可视范围的变量和函数仅在当前合约中可见。这意味着其他合约,包括继承自该合约的子合约,都无法访问这些 private 成员。
  • 实例:在 VisibilityBase 合约中,uint private x = 0; 声明了一个 private 状态变量 x。只有在 VisibilityBase 合约内部的函数才能访问 x。例如:
function accessX() private view returns (uint) {return x;
}

外部合约无法直接访问 x,继承自 VisibilityBase 的子合约也不能访问 x

 

3. external 可视范围

  • 定义external 可视范围仅适用于函数,意味着该函数只能通过外部消息调用(例如通过 this.func 的方式),而不能在合约内部直接调用。外部函数通常用于处理大量数据,因为它们可以接收 calldata,这是一种只读的、存储在合约调用栈中的数据类型,比 memory 更节省 gas。
  • 实例:在 VisibilityBase 合约中,function externalFunc() external pure returns (uint) { return 300; } 定义了一个 external 函数 externalFunc。外部合约可以通过以下方式调用:
VisibilityBase contractInstance = new VisibilityBase();
uint result = contractInstance.externalFunc();

然而,在 VisibilityBase 合约内部,不能直接调用 externalFunc,例如:

// 以下代码会报错
function internalCallExternal() public pure {externalFunc(); // 错误:不能在内部直接调用 external 函数
}

4. internal 可视范围

  • 定义internal 可视范围的变量和函数仅在合约内部以及继承自该合约的子合约中可见。在合约内部,函数可以直接调用 internal 函数,而不需要通过合约实例。
  • 实例:在 VisibilityBase 合约中,uint internal y = 1; 声明了一个 internal 状态变量 yfunction internalFunc() internal pure returns (uint) { return 100; } 定义了一个 internal 函数 internalFunc。在 VisibilityBase 合约内部,其他函数可以直接访问 y 和调用 internalFunc,例如:

function accessYAndInternalFunc() public view returns (uint) {return y + internalFunc();
}

如果有一个继承自 VisibilityBase 的子合约,子合约也可以访问 y 和调用 internalFunc。例如:

contract SubContract is VisibilityBase {function accessFromSub() public view returns (uint) {return y + internalFunc();}
}

总结

  • public:状态变量和函数可以在合约内部和外部访问。对于状态变量,Solidity 会自动生成 getter 函数。

  • private:状态变量和函数只能在当前合约内部访问,外部和其他合约无法访问。

  • internal:状态变量和函数可以在当前合约内部以及继承它的子合约中访问,但不能在外部访问。

  • external:函数只能在合约外部调用,不能在合约内部直接调用。

 

代码实例

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;contract VisibilityBase {uint private x = 0;uint internal y = 1;uint public z = 2;function privateFunc () private pure returns (uint) {return 0;}function internalFunc() internal pure returns  (uint) {return 100;        }function publicFunc() public pure returns (uint) {return 200;}function externalFunc() external pure returns (uint) {return 300;}
}

在这个合约中:

  • x 是 private,只能在 VisibilityBase 内部访问。

  • y 是 internal,可以在 VisibilityBase 及其子合约中访问。

  • z 是 public,可以在合约内部和外部访问。

  • privateFunc 是 private,只能在 VisibilityBase 内部调用。

  • internalFunc 是 internal,可以在 VisibilityBase 及其子合约中调用。

  • publicFunc 是 public,可以在合约内部和外部调用。

  • externalFunc 是 external,只能在合约外部调用。

 


http://www.ppmy.cn/news/1568174.html

相关文章

万字长文总结前端开发知识---JavaScriptVue3Axios

JavaScript学习目录 一、JavaScript1. 引入方式1.1 内部脚本 (Inline Script)1.2 外部脚本 (External Script) 2. 基础语法2.1 声明变量2.2 声明常量2.3 输出信息 3. 数据类型3.1 基本数据类型3.2 模板字符串 4. 函数4.1 具名函数 (Named Function)4.2 匿名函数 (Anonymous Fun…

全面评测 DOCA 开发环境下的 DPU:性能表现、机器学习与金融高频交易下的计算能力分析

本文介绍了我在 DOCA 开发环境下对 DPU 进行测评和计算能力测试的一些真实体验和记录。在测评过程中,我主要关注了 DPU 在高并发数据传输和深度学习场景下的表现,以及基本的系统性能指标,包括 CPU 计算、内存带宽、多线程/多进程能力和 I/O 性…

六、深入了解DI

依赖注入是⼀个过程,是指IoC容器在创建Bean时,去提供运⾏时所依赖的资源,⽽资源指的就是对象. 在上⾯程序案例中,我们使⽤了 Autowired 这个注解,完成了依赖注⼊的操作. 简单来说,就是把对象取出来放到某个类的属性中。 关于依赖注…

第 10 课 Python 内置函数 (增补)

1.enumerate enumerate() 接受一个可迭代对象作为输入,并返回一个枚举对象这个枚举对象包含了原始可迭代对象中的每个元素以及对应的索引它允许在循环中同时获取索引和值,这对于需要索引的情况非常方便 作用:在循环中需要同时访问索引和值时非…

C语言连接Mysql

目录 C语言连接Mysql下载 mysql 开发库 方法介绍mysql_init()mysql_real_connect()mysql_query()mysql_store_result()mysql_num_fields()mysql_fetch_fields()mysql_fetch_row()mysql_free_result()mysql_close() 完整代码 C语言连接Mysql 下载 mysql 开发库 方法一&#xf…

【Elasticsearch】doc_values 可以用于查询操作

确实,doc values 可以用于查询操作,尽管它们的主要用途是支持排序、聚合和脚本中的字段访问。在某些情况下,Elasticsearch 也会利用 doc values 来执行特定类型的查询。以下是关于 doc values 在查询操作中的使用及其影响的详细解释&#xff…

深度学习笔记——正则化

大家好,这里是好评笔记,公主号:Goodnote,专栏文章私信限时Free。本笔记介绍深度学习中常见的正则化。 文章目录 正则化L1 正则化(Lasso)原理使用场景优缺点 L2 正则化(Ridge)原理使用…

【论文推荐|深度学习,滑坡检测,多光谱影像,自然灾害,遥感】2022年Landslide4Sense竞赛成果:基于多源卫星影像的先进滑坡检测算法研究(五)

【论文推荐|深度学习,滑坡检测,多光谱影像,自然灾害,遥感】2022年Landslide4Sense竞赛成果:基于多源卫星影像的先进滑坡检测算法研究(五) 【论文推荐|深度学习,滑坡检测&#xff0c…