在一些合约中,我看到他们使用恒定的槽号。但他们如何保证那个插槽永远不会被使用呢?例如,在EIP1967中有一个插槽用于实现:
// bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1)
_IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
,另一个例子是在Gnosis的合同中:
// keccak256("fallback_manager.handler.address")
FALLBACK_HANDLER_STORAGE_SLOT = 0x6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d5;
问题是:使用这种方法使用任何插槽是否安全?可以在这个槽中使用一些动态数组或映射吗?例如:
// keccak256("some.dummy.address.address")
SOME_SLOT = 0x47bd68279a41c9ae1cc277c8922809c3c82881c5143963fcfc95b91a61097eb5;
以太坊写入空闲内存插槽。来自文档:
Solidity总是将新对象放置在空闲内存指针和内存永远不会被释放(这在将来可能会改变)。
如果您已经写入插槽,以太坊将不会在该插槽中存储任何内容。现在由开发者来跟踪他们已经使用过的插槽。为了定义他们将要使用的插槽,开发人员使用内联汇编。(这是内联汇编的优点之一。它提供了对内存的细粒度控制)