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