泰岳区块链-合约面试题之 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。废话少说,直接进入调试模式。

泰岳区块链-合约面试题之 solidity 合约 Map 存储

从这个图里面可以看到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。