欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 维修 > solidity基础 -- 可视范围

solidity基础 -- 可视范围

2025/2/6 8:45:39 来源:https://blog.csdn.net/Dalik1018/article/details/145401526  浏览:    关键词: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,只能在合约外部调用。

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com