文档很好地介绍了EVM中的内存布局,但我仍然有一个关于映射和数组的问题:
如果数组本身存储在插槽i中,则其值从keccak256(i(开始。在uint256的情况下,数组的每个元素因此具有作为地址的keccak256(i(+索引。但是,是什么防止两个不同的i
值具有冲突地址?即使在keccak256(x(从未为不同的x返回相同的结果的情况下,也可能是一个数组从某个地方开始(地址y(,变得更大(例如存储10000个值(,但由keccak26映射的另一个数组在y + 512
开始,因此与前一个数组重叠。这个逻辑正确吗?如果是,编译器如何防止此类冲突?
同样的问题也适用于映射
是什么防止两个不同的i值具有冲突地址
您的逻辑在理论上是正确的,但在实践中不适用。
keccak(i)
和keccak(i+1)
之间的差异如此之大,以至于两者之间可以容纳一万多个值。
如果你很幸运地找到了一个非常接近的哈希结果,那么差异可能在10^20左右(这是一个"二十个零"(。因此,再加上必须支付交易费用才能推送数组的每一项,这在实践中是不可能的。
编译器如何防止此类冲突
Solidity编译器与防止哈希冲突无关。它的任务是";仅";以将Solidity代码翻译成EVM兼容的字节码。