プログラミング

【初心者向け】Solidityにおけるmappingの使い方を解説!

今回は、Solidityにおけるmappingについて解説します。 スマートコントラクトの実装を行う際に頻出するので、ぜひ書き方を覚えておきましょう。

【初心者向け】Solidityにおけるmappingの使い方を解説!

arrow_drop_down 目次

mappingとは

mappingとは、Solidityで使用されるデータ型の一つで、いわゆる連想配列です。キーとバリューを関連付けすることができます。

単純な配列は添字が数字なのに対し、連想配列は添字に数字以外のデータ型を使用することができる配列です。

mappingの構文(書き方)

基本構文

mapping(_KeyType => _ValueType) アクセス修飾子 変数名

解説

mapping型は上のようにmapping(_KeyType => _ValueType)で宣言されます。キーはmapping、可変長配列、コントラクト、列挙型および構造体を除く全ての型を指定することができ、バリューはmappingを含む全ての型を指定できます。

mappingは、可能な全てのキーが存在するように事実上初期化され、バリューは各データ型のデフォルト値になります。keyはmappingに実際格納されているわけではなく、keccak256でハッシュ化された値が保存されており、この値を用いてバリューは調べられます。

サンプルコード

アドレスとユーザの情報(年齢)を対応づけるmappingコード

pragma solidity ^0.4.22;

contract MappingExample {
  mapping(address => uint) public users;

  function addUser(uint _age) public {
    if(users[msg.sender] == 0){  
      users[msg.sender] = _age;    
    }
  }
  
  function getUser() public view returns (uint) {
    return users[msg.sender];
  }
}

解説

mappingの宣言

  mapping(address => uint) public users;

 これは、アドレスと年齢を対応づけるmapping型の変数usersを宣言しています。usersはkeyをaddress型、valueをuint型とした配列です。


データ追加メソッド

function addUser(uint _age) public {
    if(users[msg.sender] == 0){
      users[msg.sender] = _age;
    }
}

これは、usersにデータを登録する関数addUserを宣言しています。

1行目はmsg.senderの年齢が登録されていないかどうか比較しています。

他言語において値が代入されていない場合、nullやundefinedが返ってきますが、solidityの場合、デフォルト値0(型によりデフォルト値は異なります)が返ってくるため、このような条件式になります。

2行目は、年齢を登録する式になっています。

mappingは配列と同様の方法で、値を代入することができます。また、msg.senderはこのメソッドを呼び出したアドレスが値として入っており、それをkeyとしてmappingにアクセスし、年齢をvalueに格納します。


データ確認メソッド

function getUser() public view returns (uint) {
    return users[msg.sender];
}

これは、登録した名前を取得する関数getUserを宣言しています。

このメソッドを呼び出したアドレスをkeyとしたvalueが返ってきます。

特殊なvalue

上でも記述した通り、valueには全ての型を使用することができます。数ある型の中で形が特殊である、構造体とmapping型の使用例を見ていきます。

宣言方法

struct User {
    string name;
    uint age;
}
mapping(address => User) public users;
mapping(address => mapping(address => uint256)) public allowance;

usersはkeyをaddress型、valueを構造体Userとした配列です。

allowanceはkeyをaddress型、valueをuint256型とした二次元配列です。


代入方法

users[msg.sender].name = "urata";
users[msg.sender].age = 29;
allowance[from][msg.sender] = 100;

keyをmsg.senderとしたvalueのnameに”urata”、ageに29を代入しています。

keyをfrom、msg.senderとしたvalueに100を代入しています。

まとめ

今回はmappingの使用方法について解説していきました。

いかがでしたでしょうか?

valueにはどんな型でも使用することができます。比較の際は、型のデフォルト値に気をつけましょう。

mappingは重要なデータ型です。実際の実装でも使用することが多いので覚えておきましょう。