众所周知,Solidity库不能有状态变量。 如果今天你在网上快速搜索一下Solidity库是否可以有状态变量,你会发现答案是否定的,它们不能。 以下是关于库的Solidity文档: 注意第一个限制

本文是由股票小能手创作,主要讲解的是如何在Solidity库中使用状态变量函数预计阅读时间3分钟,共计有1072个文字,话不多说下面一起来了解一下股票小能手的介绍吧,希望可以帮助到大家!

众所周知,Solidity库不能有状态变量。

如果今天你在网上快速搜索一下Solidity库是否可以有状态变量,你会发现答案是否定的,它们不能。

以下是关于库的Solidity文档:

注意第一个限制:库不能具有状态变量。

但文档将显示,可以通过这种方式将存储指针传递到库函数并访问状态变量。

但是如果您想在库中定义、创建和使用新的状态变量,并且在不将它们作为参数传递的情况下使用它们呢?

如果您想随时随地修改所需的合约存储,而又不传递存储指针怎么办?

使用Solidity库可以做这些事情吗?

从Solidity文档看,答案似乎是否定的。如果您像我一样在网上搜索如何执行此操作,那么您可能会发现答案是否定的,除非您当然找到了此博客文章。

所以我会说:

Solidity库可以有状态变量!

我讨厌与Solidity文档发生冲突,而且几乎所有在这一点上了解Solidity的人都是如此。

请注意库限制底部的小行:

(这些可能会在以后解除。)

好吧,库不能具有状态变量的第一个限制已于2020年3月10日解除,没有人注意到把。

将状态变量添加到库中不仅仅是一个很好的技术技巧。具有状态变量的库非常有用。

如何向库中添加状态变量

通过使用Diamond(方块)存储,库可以拥有/创建/使用/修改状态变量。

从Solidity 0.6.4开始,可以在合约存储的任意位置创建指向结构的指针。

那就是Diamond(方块)存储。报价来自Diamond(方块)标准的合约存储部分。Diamond(方块)标准和实施Diamond(方块)的人们一直在引领Diamond(方块)存储的使用。

为了更好地理解如何使用Diamond(方块)存储向库添加状态变量,请参见下面的示例。

带有状态变量的库示例

这是带有状态变量的库的简单示例。它是为了易于阅读和理解而编写的。它编译时没有错误或警告。

// SPDX-License-Identifier: MIT

pragma solidity ^0.7.0;

// This library has the state variables 'contractAddress' and 'name'

library Library {

// defining state variables

struct DiamondStorage {

address contractAddress;

string name;

// ... any number of other state variables

}

// return a struct storage pointer for accessing the state variables

function diamondStorage()

internal

pure

returns (DiamondStorage storage ds)

{

bytes32 position = keccak256("diamond.standard.diamond.storage");

assembly { ds.slot := position }

}

// set state variables

function setStateVariables(

address _contractAddress,

string memory _name

)

internal

{

DiamondStorage storage ds = diamondStorage();

ds.contractAddress = _contractAddress;

ds.name = _name;

}

// get contractAddress state variable

function contractAddress() internal view returns (address) {

return diamondStorage().contractAddress;

}

// get name state variable

function name() internal view returns (string memory) {

return diamondStorage().name;

}

}

// This contract uses the library to set and retrieve state variables

contract ContractA {

function setState() external {

Library.setStateVariables(address(this), "My Name");

}

function getState()

external

view

returns (address contractAddress, string memory name)

{

contractAddress = Library.contractAddress();

name = Library.name();

}

}

请注意,库函数setStateVariables、contractAddress和name()是内部函数。这些内部函数将被添加到ContractA的字节码中,从而增加它的大小。但是内部函数调用比外部调用使用更少的气体,所以这很好。

可以将库函数设置为外部函数,它们仍将起作用。在这种情况下,它们不会被添加到ContractA的字节码中。它们将使用委托代码操作码从外部调用??夂褪钦庋ぷ鞯?。

请注意,不同的库将需要使用不同的存储插槽,因此使用不同的keccak256ed字符串。这是为了防止两个或多个库在合同存储中写入相同的位置。



上一篇:以太坊大堵、手续费创历史新高,于是Layer 2项目火了

下一篇:区块链技术正向平台化组件化集成化演进

本文内容来自网络,如有侵犯请联系站长,本文主要讲解的事 如何在Solidity库中使用状态变量函数,如有转载请携带本站链接地址:http://www.tapmw.com/qukuailian/19910.html