泰岳区块链-合约面试题之 solidity 合约 Map 存储
面试题:Solidity中Map是如何存储的?
泰岳区块链采用的是EVM solidity合约。那么Map在solidity合约里面到底怎么存储的呢?我们写一个测试用例来测试一下。
pragma solidity ^0.6.0;
// SPDX-License-Identifier: MIT
contract Test1{
uint256 public pID;
uint256 public rID;
string public contractName;
//简单写一个玩家id,
mapping(uint256=>uint256) public plyid; //rid -> pid
mapping(address=>uint256) public plyAddr_id;
constructor() public{
rID = 1;
contractName = "test1";
}
function joinGame() public{
if (plyAddr_id[msg.sender] == 0){
pID++;
plyAddr_id[msg.sender] = pID ;
plyid[rID] = pID;
}
}
}
这个是一个简单的存储合约,用户地址可以调用。
里面存储的变量有:uint256 ,string 和map
先对solidity的存储有一个大概的了解。
solidity存储分为两种:storage和memory 。storage存储是永久存储的(任何修改都需要消耗gas)storage一般放到构造函数声明,memory是临时存储,比如函数传参,返回值,函数内部调用。
针对这个面试题,主要是要了解storage。废话少说,直接进入调试模式。
从这个图里面可以看到5个storage存储空间,刚好匹配的是我定义的5个存储,因为EVM存储都是存储在默克耳树上面。所以都是KEY/Value形式,
其中2,3,4 key 是0,1,2这些事标准的变量。分别是,pID,rID和contractName,另外两个map,其实都是根据map里面的key/value来生成对于的存储key,比如5,就是我最开始的加入游戏生成的1,如果我再加入一个值,这个storage就会多出一个,也就是说吗:
Map在solidity存储其实也就是key/value的存储。这个key 0xf4f7797edbff68274daf92f2532a33b46087e1df1e392890bd510c458053e66c 生成是这么生成的,首选这个存储的是plyAddr_id它里面的key是address,所以会用这个address+偏移量,这些都是会扩产到32位去处理。最后拿相加的结果进行Hash。得到这个地址索引的key。