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

solidity基础 -- 可视范围

        在 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,只能在合约外部调用。

 

原文地址:https://blog.csdn.net/Dalik1018/article/details/145401526
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.kler.cn/a/526589.html

相关文章:

  • Blazor-@inject
  • [前端开发]记录国内快速cdn库,用于在线引入JavaScript第三方库
  • ubuntu20.04.6下运行VLC-Qt例子simple-player
  • ChatGPT-4o和ChatGPT-4o mini的差异点
  • Vue.js组件开发深度指南:从零到可复用的艺术
  • Linux内核中container_of宏深度刨析
  • 算法题(52):翻转二叉树
  • @Inject @Qualifier @Named
  • LangChain教程 - RAG - PDF解析
  • Three.js 后期处理(Post-Processing)详解
  • 【AI】Deepseek本地部署探索,尝试联网搜索
  • react中如何获取dom元素
  • 【2024年华为OD机试】(B卷,100分)- 热点网站统计(Java JS PythonC/C++)
  • 使用DeepSeek API生成Markdown文件
  • 使用Ollama和Open WebUI快速玩转大模型:简单快捷的尝试各种llm大模型,比如DeepSeek r1
  • 33【脚本解析语言】
  • 知识推理简要介绍
  • Letta - 构建有状态LLM应用程序
  • OpenCV实战:车辆统计
  • UML状态机图-并发的表示方法