0%

solidity | 映射

solidity 的映射相当于 python 中的 map,通常用来存储数据用。

关键字 mapping

  • mapping(address => uint) public balances;
    • 键类型不能是变长数组、合约类型、嵌套类型
    • 值类型没有限制
  • 索引访问 balances[address]
    • 访问不存在的值,返回的是默认值
1
2
3
4
5
6
7
8
9
10
11
pragma solidity ^0.4.18;

contract Test{

mapping(address => uint) public balances;


function set(uint balance) public{
balances[msg.sender] = balance;
}
}

原生 mapping 局限性

  • 只能作为状态变量
    • 无法遍历
    • 没有长度
    • 没有键集合、值集合

iterable_mapping

这个库是结构体,可以理解为是一个类似 class 的自定义结构。

我们新建一个 sol 文件,取名 iterable_mapping ,然后把文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
library IterableMapping
{
struct itmap
{
mapping(uint => IndexValue) data;
KeyFlag[] keys;
uint size;
}
struct IndexValue { uint keyIndex; uint value; }
struct KeyFlag { uint key; bool deleted; }
function insert(itmap storage self, uint key, uint value) returns (bool replaced)
{
uint keyIndex = self.data[key].keyIndex;
self.data[key].value = value;
if (keyIndex > 0)
return true;
else
{
keyIndex = self.keys.length++;
self.data[key].keyIndex = keyIndex + 1;
self.keys[keyIndex].key = key;
self.size++;
return false;
}
}
function remove(itmap storage self, uint key) returns (bool success)
{
uint keyIndex = self.data[key].keyIndex;
if (keyIndex == 0)
return false;
delete self.data[key];
self.keys[keyIndex - 1].deleted = true;
self.size --;
}
function contains(itmap storage self, uint key) returns (bool)
{
return self.data[key].keyIndex > 0;
}
function iterate_start(itmap storage self) returns (uint keyIndex)
{
return iterate_next(self, uint(-1));
}
function iterate_valid(itmap storage self, uint keyIndex) returns (bool)
{
return keyIndex < self.keys.length;
}
function iterate_next(itmap storage self, uint keyIndex) returns (uint r_keyIndex)
{
keyIndex++;
while (keyIndex < self.keys.length && self.keys[keyIndex].deleted)
keyIndex++;
return keyIndex;
}
function iterate_get(itmap storage self, uint keyIndex) returns (uint key, uint value)
{
key = self.keys[keyIndex].key;
value = self.data[key].value;
}
}

这个内容粘到新建的文件中,和我们的主 sol 文件同一级别。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
pragma solidity ^0.4.18;

import "./iterable_mapping.sol";

contract Test{

IterableMapping.itmap data;

function insert(uint k,uint v) public returns(uint size){
IterableMapping.insert(data,k,v);
return data.size;
}

function sum() public constant returns(uint s){
for(uint i = IterableMapping.iterate_start(data); IterableMapping.iterate_valid(data,i); i = IterableMapping.iterate_next(data,i))
{
uint key;
uint value;
(key,value) = IterableMapping.iterate_get(data,i);
s += value;
}
}
}
请我喝杯咖啡吧~