---
title: "Solidityのmappingとは？"
description: "Solidityのmappingの仕組みを学ぶ"
---

# Solidityのmappingとは？

[Solidity](https://www.alchemy.com/overviews/solidity)におけるマッピングとは、キーと値のペアとしてデータを格納するハッシュテーブルであり、キーにはEthereumがサポートする組み込みデータ型のいずれかを使用できる。マッピングは[Solidity開発を学ぶ](https://www.alchemy.com/overviews/learn-solidity)上で理解すべき基本概念である。

本記事では、マッピングとは何か、マッピングの仕組み、マッピングと配列の違いについて説明し、Ethereumおよび Optimism、Arbitrumのような Solidity互換ブロックチェーン上で優れたスマートコントラクトを開発できるよう、マッピングの例を示す。

## **ハッシュテーブルとは**

ハッシュテーブルとは、データを連想的に格納するデータ構造である。ハッシュテーブルではデータが配列形式で保持され、各データ値は固有のインデックス値を持つ。ハッシュテーブルは配列を格納媒体として使用し、ハッシュ技法を用いて要素を挿入または検索するためのインデックスを確立する。

<ImageBlock
  src="https://media.alchemy.com/1703922693-mapping-in-solidity.png"
  alt="Mappings in Solidity Explained by Doug Crescenzi"
  width={429}
  height={329}
  caption="Source: Mappings in Solidity Explained by Doug Crescenzi"
/>

必要なデータのインデックスが分かっていれば、非常に高速に返すことができる。そのため、ハッシュテーブルはデータ量にかかわらず、挿入と検索の操作が非常に高速なデータ構造である。

## **Solidityにおけるマッピングとは**

マッピングは、Solidityにおいてキーと値のペアとしてデータを格納するハッシュテーブルであり、キーには参照型を除く組み込みデータ型のいずれかを使用でき、値のデータ型には任意の型を使用できる。

マッピングは、Solidityおよび Ethereumブロックチェーンにおいて、固有の Ethereumアドレスを対応する値の型に紐付けるために最も一般的に使用される。

他のプログラミング言語では、マッピングは辞書に相当する。

### ハッシュテーブルとSolidityマッピングの違いとは

マッピングはハッシュテーブルとして機能し、キー型と対応する値型のペアを持つ。マッピングは多数の**_KeyType_**を**_ValueType_**に紐付けられる点で有用である。マッピングには長さの概念がなく、キーや値を「設定する」という概念もない。マッピングは、参照型を格納する状態変数にのみ適用可能である。マッピングが初期化されると、あらゆる可能なキーが含まれ、それらはバイト表現がすべてゼロの値にマッピングされる。

Solidityにおけるマッピングの定義方法は、他の変数型と同様である。

### SolidityにおけるarrayとMappingの違いとは

[**Solidityのarray**](https://www.alchemy.com/overviews/solidity-arrays)は、既知のキーに基づいて値を取得できるマッピングと比較して、データ群を反復処理する場合（例えばforループを使用する場合）に適している。

Solidityにおいて配列を反復処理することはマッピングからデータを取得することに比べてコストが高くなり得るため、また開発者がスマートコントラクト内に値とそのキーの両方を保存したい場合があるため、開発者は時にキーの配列を作成し、それを参照としてマッピング内部からデータを取得できるようにする。

大きな配列を反復処理すると、そのトランザクションの価値以上に Solidityのガス手数料がかかる可能性があるため、開発者はSolidityの配列を大きくしすぎるべきではなく、マッピングの方が[ガス効率の良いスマートコントラクト実装](https://www.alchemy.com/overviews/solidity-gas-optimization)となる。

**マッピングに関するその他の性質は以下の通りである：**

- マッピングには長さがない。
- マッピングには、キーまたは値が「設定される」という概念もない。
- マッピングは、ストレージ参照型として機能する状態変数にのみ使用できる。

## **ネストされたマッピングとは**

ネストされたマッピングとは、あるマッピングから別のマッピングへのマッピングである。例えば、ユーザー名と年齢があり、特定のIDを用いてこの情報を保存し、他者がそのIDを用いてのみそれを取得できるようにしたい場合、これはSolidityにおける二重マッピングと呼ばれる。

以下はネストされたマッピングの例である：

このコントラクトでは、Userと呼ばれる1つのネストされたマッピングを構築した。そのマッピング内で、以下の2つのマッピングを連結している：

1. 特定ユーザーのIDに関する情報を記録するためのもの
1. 特定ユーザーの名前と年齢を保存するためのもの

以下のコードブロックは単純なgetter関数であり、ユーザーの情報を返す。

## **Solidityにおけるマッピングの使い方**

以下はSolidityにおけるマッピングの使用例である。次のコードスニペットの機能は以下の通りである：

- addressからuintへのマッピングであり、マッピングが常に値を返すことを保証する
- 値が一度も設定されていない場合、デフォルト値を返す。
- マッピングされたアドレスの値を更新する
- 値をデフォルト値にリセットする。
- addressから別のマッピングへのネストされたマッピングを作成する
- 初期化されていない場合でもネストされたマッピングから値を取得する

## **Solidityマッピングの例**

以下はSolidityにおけるマッピングの3つの例である：

1. ERC20トークンの残高
1. ブール論理の使用
1. DAOのメンバー確認

### **1. ERC20ユーザー残高**

このコードスニペットは、ユーザーのアドレスをそのアドレスのERC20残高に紐付ける。

### **2. Solidityマッピング bool の例**

このコードスニペットは、候補者名をリストにまとめ、その候補者が獲得した票数を返すよう設計されている。この例は、メンバーが組織の意思決定について投票することが想定される[DAO](https://www.alchemy.com/dapps/top/daos)においてユースケースを持つ。

### **3. メンバーであるかどうか（DAO）**

この例は、_raisedProposals_、_stakeholderVotes_、_votedOn_、_contributors_、_stakeholders_をマッピングするDominion DAOのスマートコントラクトからのものである。

このコード例は、2つの[Solidity構造体](https://www.alchemy.com/overviews/solidity-struct)である_ProposalStruct_と_VotedStruct_のフィールドを列挙している。

## **Solidityの文字列マッピング**

理解を深めるため、マッピングを構築しながらいくつかの値を追加してみよう。以下の例では、以下を行う：

- コントラクトを作成する
- 構造体を定義する
- 構造体の各要素を宣言する
- マッピングを作成する
- マッピングに値を追加する

## **SolidityマッピングのFAQ**

Solidityマッピングに関するよくある質問をいくつか挙げる：

1. Solidityマッピングの長さとは何か
1. Solidityマッピングのデフォルト値とは何か
1. Solidityマッピングを公開して確認するにはどうすればよいか

### **Solidityマッピングの長さとは**

**マッピングには長さがない。キーのデータそのものはマッピングに保存されず、代わりにそのkeccak256ハッシュ**が、キーデータが指す値を格納するために使用される。キーと値がそれ自体として存在するという概念は存在しない。

### **Solidityマッピングのデフォルト値の型とは**

以下はSolidityマッピングのデフォルト値の型である：

- **int/uint** - key type = yes; value type = yes
- **string** - key type = yes; value type = yes
- **byte/bytes** - key type = yes; value type = yes
- **address** - key type = yes; value type = yes
- **struct** - key type = no; value type = yes
- **mapping** - key type = no; value type = yes
- **enum** - key type = no; value type = yes
- **contract** - key type = no; value type = yes
- **fixed-sized array** - key type = yes; value type = yes
- **dynamic-sized array** - key type = no; value type = yes
- **multi-dimensional array** - key type = no; value type = yes
- **variable** - key type = no; value type = no

### **Solidityマッピングを公開して確認する方法**

[プロパティがpublicである](https://www.alchemy.com/overviews/solidity-function-visibility)場合、**Solidityコンパイラ**が生成するgetter関数を使用してアクセスできる。
