售前客服二维码
文章均源于网络收集编辑侵删
提示:仅接受技术开发咨询!
众所周知,实度库不能有状态变量。
如果你今天在网上快速搜索一下实度库是否可以有状态变量,你会发现答案是否定的,它们不能。
以下是关于库的可靠度文档:
注意第一个限制:库不能有状态变量。
但是,该文档将显示存储指针可以传递给库函数,并且可以通过这种方式访问状态变量。
但是,如果您想要在库中定义、创建和使用新的状态变量,并且在不将它们作为参数传递的情况下使用它们,会怎么样呢?
如果您想随时随地修改所需的合同存储而不传递存储指针,该怎么办?
你能用实度图书馆做这些事情吗?
从实度文档来看,答案似乎是否定的。如果你像我一样在网上搜索如何做到这一点,你可能会发现答案是否定的,除非你确实找到了这篇博文。
所以我会说:
实体库可以有状态变量!
我讨厌与实性文档的冲突,这是每个知道实性的人的真实情况。
请注意库限制底部的小线条:
(这些可能稍后发布。(
图书馆不能有状态变量的第一个限制是在2020年3月10日取消的,没有人注意到。
将状态变量添加到库中不仅是一项好的技术技能。带有状态变量的库非常有用。
如何向库中添加状态变量
通过使用菱形存储,库可以拥有/创建/使用/修改状态变量。
从实度0.6.4开始,指向结构的指针可以在契约存储中的任何地方创建。
那是钻石仓库。报价来自钻石标准的合同存储部分。钻石(块)标准和实施钻石(块)的人一直在领导钻石(块)存储的使用。
为了更好地理解如何使用钻石存储向库中添加状态变量,请参见以下示例。
带有状态变量的库示例
这是一个带有状态变量的库的简单例子。这是为了便于阅读和理解而写的。它编译时没有错误或警告。
//SPDX-许可证标识符: MIT
务实稳健的^0.7.0;
//这个库有状态变量“合同地址”和“名称”
图书馆
//定义状态变量
struct DiamondStorage {
地址合同地址;
字符串名称;
//.任何数量的其他状态变量
{}
//返回用于访问状态变量的结构存储指针
函数diamondStorage()
内部的
纯的
返回(DiamondStorage存储ds)
{
字节32位置=keccak 256(‘diamond . standard . diamond . storage’);
组件{ ds.slot :=位置}
{}
//设置状态变量
函数setStateVariables(
地址_合同地址,
字符串内存名称
(
内部的
{
钻石存储ds=钻石存储();
ds . contract ADdress=_ contract ADdress;
ds.name=_ name
{}
//获取合同地址状态变量
函数contractAddress()内部视图返回(地址){
返回diamondStorage()。合同地址。
{}
//获取状态变量名称
函数名()内部视图返回(字符串内存){
返回diamondStorage()。名称;
{}
{}
//这个契约使用库来设置和检索状态变量
合同合同A {
函数setState()外部{
库。设置状态变量(地址(此),“我的名字”);
{}
函数getState()
外部
视角
返回(地址合同地址,字符串内存名称)
{
合同地址=库。合同地址();
名称=库。名称();
{}
{}
请注意,库函数setStateVariables、contractAddress和name()是内部函数。这些内部函数将被添加到ContractA的字节码中,从而增加它的大小。但是内部函数调用比外部调用使用更少的气体,所以这是好的。
您可以将库函数设置为外部函数,它们仍然可以工作。在这种情况下,它们不会被添加到契约的字节码中.将使用委托代码操作码从外部调用它们。这就是库函数的工作原理。
请注意,不同的库需要使用不同的存储插槽,因此将使用不同的keccak256ed字符串。这是为了防止两个或多个库写入合同存储中的同一位置。
文章均源于网络收集编辑侵删
提示:仅接受技术开发咨询!