编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

区块链Solidity语言映射类型深入详解|入门系列

wxchong 2024-09-25 23:21:50 开源技术 21 ℃ 0 评论

映射[1]是一种引用类型,存储键值对,提供根据键查找值,与其它语言中的字典,map等类似,但也有非常大的不同,尤其它在区块链中独特的存储模型。

1. 只能是状态变量

由于在映射中键的数量是任意的,导致映射的大小也是变长的。映射只能声明为storage的状态变量,或被赋值给一个storage的对象引用。我们来看下面的示例:

在上面的示例中,我们声明了storage的状态变量stateVar,可以对其增加新键值对;也能通过引用传递的方式赋值给storage的引用storageRef。

2. 支持的类型

映射类型的键支持除映射,变长数组,合约,枚举,结构体以外的任意类型。值则允许任意类型,甚至是映射。下面是一个简单的例子代码:

3. setter方法

对于映射类型,也能标记为public。以让Solidity为我们自动生成访问器。

在上面的例子中,如果要访问intMapp[1],输入值1。而如果要访问嵌套的映射mapMapp[2][2],则输入两个键对应的值2,2即可。

4. 映射的存储模型

由于状态变量是存储在区块链上的,所以存储空间需要预先分配,但映射的存储值是可以动态增改的,那么最终是如何支持的呢。关于状态的存储模型[2]里面提到,实际存储时是以哈希键值对的方式。其中哈希是由键值和映射的存储槽位序号拼接后计算的哈希值(映射只占一个槽位序号),也就是说值是存到由keccak256(k . p)计算的哈希串里,这里的k表示的是映射要查找的键,p表示映射在整个合约中相对序号位置。

下面我们将通过例子,先用合约给一个映射类型设置一个值,再用web3.js提供的getStorageAt()方法将值取出来。

上面的智能合约代码中,我们为strMapping的键aaa存入值aaa。


上面的代码中,getStorageAt的第一个参数是合约地址,第二个参数是键和映射所在槽序号的哈希值。通过填入这两个参数,最终获得了在合约中存储的值0x6161610000000000000000000000000000000000000000000000000000000006[2]。

5. 与其它语言映射的不同

由于映射的存储模型决定了,映射实际不存在一个映射的键大小,没有一个键集合的概念。但我们可以通过扩展默认映射来实现这样的功能,官方有个扩展示例[3]:

关于作者

专注基于以太坊(Ethereum)的相关区块链(Blockchain)技术,了解以太坊,Solidity,Truffle,web3.js。

个人博客: http://me.tryblockchain.org

版权所有,转载注明出处

参考资料


  1. http://solidity.readthedocs.io/en/develop/types.html#mappings ?

  2. 状态变量的存储模型: http://www.tryblockchain.org/Solidity-LayoutOfStateVariablesInStorage-状态变量的存储模型.html ?

  3. 官方提供的映射扩展示例:https://github.com/ethereum/dapp-bin/blob/master/library/iterable_mapping.sol ?

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表