本文へスキップ
BecomeCoder

Solidityコース · 第3章 値とデータ構造 ― address・mapping・struct · レッスン12

mapping ― 鍵から値を引く住所録

ブラウザで完結

導入

「アドレスごとの残高」「ユーザーIDごとの名前」のように、鍵(key)から値(value)を引くデータ構造mapping です。トークンやゲームの所持品など、Solidity で最も使うデータ構造と言っても過言ではありません。

説明

mapping(鍵の型 => 値の型) の形で宣言します。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract Bank {
    // アドレス → 残高 の対応表
    mapping(address => uint256) public balances;

    function deposit(uint256 amount) public {
        balances[msg.sender] = balances[msg.sender] + amount;
    }

    function balanceOf(address who) public view returns (uint256) {
        return balances[who];
    }
}
  • mapping(address => uint256) public balances; … アドレスをキーに残高を引ける表。public なので balances(アドレス) で外から読める。
  • balances[msg.sender] … 呼び出した本人の残高にアクセス。
  • 未登録のキーはゼロ値:まだ入れていないアドレスを引くと、エラーではなく 0 が返る(uint のゼロ値)。
graph LR
    K1["0x5B38...ddC4"] --> V1["残高: 100"]
    K2["0xAb84...cb2A"] --> V2["残高: 250"]
    K3["0x4B20...C777"] --> V3["残高: 0(未登録)"]

注意点として、mapping は「全キーを一覧する」ことができません(どのキーが使われたかを内部で覚えていない)。全ユーザーを列挙したいなら、別途アドレスの配列を用意して自分で管理します。

やってみよう

mapping は「巨大な棚に、鍵で一発で目的の引き出しを開ける」イメージです。配列のように順番に探さないので、キー指定のアクセスがとても高速(=ガスも抑えられる)。ただし「棚にどの引き出しを使ったか」のリストは別管理が要る、と覚えておきましょう。

実際に動かしてみよう

下のエディタのコントラクトを「コンパイル & デプロイ」すると、ブラウザ内で本物のSolidityコンパイラ(solc)がコンパイルし、EVM(@ethereumjs)にデプロイされます。デプロイ後は public な関数がボタンになって並ぶので、引数を入れて呼び出すと戻り値・イベント・require のエラー(revert理由)まで確認できます。本文のコントラクトを書き換えて動きを試しながら進めましょう(コンパイラ本体は初回だけ読み込みに数秒かかります)。

Solidity — ブラウザ内でコンパイル & 実行

ブラウザ内で本物のSolidityコンパイラ(solc)とEVM(@ethereumjs)を動かす環境を読み込みます(コンパイラ本体は初回のコンパイル時に読み込むため、最初の実行だけ数秒かかります)。
スクロールして表示された時点でも自動で読み込まれます。