
众所周知,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:MITpragmasolidity^0.7.0;//Thislibraryhasthestatevariables'contractAddress'and'name'libraryLibrary{//definingstatevariablesstructDiamondStorage{addresscontractAddress;stringname;//...anynumberofotherstatevariables}//returnastructstoragepointerforaccessingthestatevariablesfunctiondiamondStorage()internalpurereturns(DiamondStoragestorageds){bytes32position=keccak256("diamond.standard.diamond.storage");assembly{ds.slot:=position}}//setstatevariablesfunctionsetStateVariables(address_contractAddress,stringmemory_name)internal{DiamondStoragestorageds=diamondStorage();ds.contractAddress=_contractAddress;ds.name=_name;}//getcontractAddressstatevariablefunctioncontractAddress()internalviewreturns(address){returndiamondStorage().contractAddress;}//getnamestatevariablefunctionname()internalviewreturns(stringmemory){returndiamondStorage().name;}}//ThiscontractusesthelibrarytosetandretrievestatevariablescontractContractA{functionsetState()external{Library.setStateVariables(address(this),"MyName");}functiongetState()externalviewreturns(addresscontractAddress,stringmemoryname){contractAddress=Library.contractAddress();name=Library.name();}}请注意,库函数setStateVariables、contractAddress和name()是内部函数。这些内部函数将被添加到ContractA的字节码中,从而增加它的大小。但是内部函数调用比外部调用使用更少的气体,所以这很好。
可以将库函数设置为外部函数,它们仍将起作用。在这种情况下,它们不会被添加到ContractA的字节码中。它们将使用委托代码操作码从外部调用。库函数就是这样工作的。
请注意,不同的库将需要使用不同的存储插槽,因此使用不同的keccak256ed字符串。这是为了防止两个或多个库在合同存储中写入相同的位置。
Solidity發布0.8.13版本,修復abi.encodeCall相關重要bug
Moonbeam新增Scaffold-ETH支持部署Solidity智能合約
Filecoin 將分階段推出 EVM 兼容的 Filecoin 虛擬機,首階段版本將于 2021 年第 4 季度上線
Solidity 發布 0.8.10 版本,為純 Yul 模式啟用新的 EVM 代碼生成器
在 Solana 上構建 EVM 開發環境的 Neon Labs 獲 Jump Capital 領投的 4000 萬美元融資
EthHub 聯合創始人:Layer 2 時代已來臨,公鏈競爭格局會發生什么改變?
Optimism 用以支持非營利和開源軟件項目的 100 萬美元捐款已分配完畢,Ethersjs、go-ethereum 等項目在列
Optimism 將于 11 月 11 日部署 OVM 2.0 版,將實現 EVM 等效性
DeFi 保險協議 InsurAce 推出 DeFi 保險 API 集成服務
Optimism:為什么 EVM 等效必須成為 L2 通用標準?
Optimism:EVM Equivalence 完全符合以太坊虛擬機規范,將成為 L2 下一個通用標準
無需許可的二次融資協議 CLR.fund 啟動第八輪二次融資
a16z 前合伙人:從架構角度深入解析 Web 3.0 與 Web 2.0 應用區別
穩定幣兌換協議 Shell Protocol 發布 V2 版本路線圖
隱私公鏈 Findora 上線開發者網絡,已支持通過 EVM 部署智能合約
Nethermind Warp 將演示把 Uniswap V3 轉換到 Cairo 并將其部署在 StarkNet 上
Optimism 將升級為 EVM 全兼容,開發者可使用 Solidity 智能合約直接部署
Pantera Capital:為什么 Layer 2 將解鎖下一波區塊鏈殺手級應用?
Crypto.com 的 EVM 兼容鏈 Cronos 主網將于 10 月 19 日上線
Matter Labs 推迟上线 zkSync 2.0,将在几周后分阶段开放测试网



