Solidity提供了其他编程语言中常见的数据结构。 除了数字和结构等简单值之外,还有一些数据类型可以在添加更多数据时动态扩展, 这些动态类型的三个主要类别是:
mapping(bytes32 => uint256),mapping(address => string)等。
数组:[] uint256,[] byte等。
字节数组: 只有两种:字符串和字节。
在本系列的第二部分中,我们已经看到了在存储中表示具有固定大小的简单类型。
基本值:uint256,byte等。
固定大小的数组:[10] uint8,[32]字节,bytes32。
结合上述类型的结构。
具有固定大小的存储变量在存储中一个接一个地布局,尽可能紧密地打包在32个字节的块中。
在本文中,我们将研究Solidity如何支持更复杂的数据结构。 Solidity中的数组和映射在表面上可能看起来很熟悉,但它们的实现方式使它们具有完全不同的性能特征。
我们将从mapping开始,这是三个中最简单的。 事实证明,数组和字节数组只是具有更高级功能的映射。
mapping
让我们在uint256 => uint256映射中存储单个值:
pragma solidity ^0.4.11;
contract C {
mapping(uint256 => uint256) items;
function C() {
items[0xC0FEFE] =0x42;
}
}
编译:
solc --bin --asm --optimize c-mapping.sol
组合:
tag_2:
// Doesn't do anything. Should be optimized away.
0xc0fefe
0x0
swap1
dup2
mstore
0x20
mstore
// Storing 0x42 to the address 0x798...187c
0x42
0x79826054ee948a209ff4a6c9064d7398508d2c1909a392f899d301c6d232187c
sstore
我们可以将EVM存储视为键值数据库,每个键限制为存储32个字节。 不是直接使用密钥0xC0FEFE,而是将密钥散列为0x798 ... 187c,并将值0x42存储在那里。 使用的散列函数是keccak256(SHA256)函数。
在这个例子中,我们没有看到keccak256指令本身,因为优化器决定预先计算结果并将其内联到字节码中。 我们仍然以无用的mstore指令的形式看到这种计算的痕迹。
领取专属 10元无门槛券
私享最新 技术干货