映射类型
作用:
映射是一种引用类型,存储键值对,提供根据键查找值,与其它语言中的字典类似,但也有不同
定义(声明) :
由于在映射中键的数量是任意的,导致映射的大小也是变长的。映射只能声明为storage的状态变量,或被赋值给一个storage的对象引用。
声明举例:
mapping(uint => uint) stateVar;
赋值(建立映射):
storageRef[1] = uint(64);// 将64赋值给map映射的1
pragma solidity ^0.4.0;
contract StateVariableOnly{
//状态变量
mapping(uint => uint) stateVar;
//uint 对应 uint 这个映射就类似于数组了
//当然也可以string 对应 uint 等
function mappingTest() returns (uint){
//可以被赋值为storage的引用
mapping(uint => uint) storageRef = stateVar; //引用传值,传指针
storageRef[1] = uint(64);// 将64赋值给map映射的1
return storageRef[1];
}
}
可建立映射的类型:
键 | 除了映射,变长数组,合约,枚举,结构体以外的任意类型 |
值 | 允许任意类型,甚至是映射 |
举例:
pragma solidity ^0.4.0;
contract MappingType{
struct s{
string name;
uint8 age;
}
mapping(bytes => s) structMapping;
mapping(address => s) addrMapping;
mapping(string => mapping(uint => s)) complexMapping;
}
setter方法:
对于映射类型,也能标记为
public
。以让Solidity为我们自动生成访问器。
测试代码:
pragma solidity ^0.4.0;
contract MappingGetter{
mapping(uint => uint) public intMapp;
mapping(uint => mapping(uint => string)) public mapMapp;
function set(){
intMapp[1] = 100;
mapMapp[2][2] = "aaa";
}
}
映射在区块链中的储存模型:
具体代码参见:http://me.tryblockchain.org/solidity-mapping.html
由于状态变量是存储在区块链上的,所以存储空间需要预先分配,但映射的存储值是可以动态增改的,那么最终是如何支持的呢。关于状态的存储模型里面提到,实际存储时是以哈希键值对的方式。其中哈希是由键值和映射的存储槽位序号拼接后计算的哈希值(映射只占一个槽位序号),也就是说值是存到由keccak256(k . p)计算的哈希串里,这里的k表示的是映射要查找的键,p表示映射在整个合约中相对序号位置。
如何从哈希串提取到键值对信息?
答:可用web3.js提供的getStorageAt()方法将值取出来
getStorageAt的第一个参数是合约地址,第二个参数是键和映射所在槽序号的哈希值。