コンテンツへスキップ
0%

Solidityのmappingとは?

Alchemy team headshot

執筆者 Alchemy

2022年10月4日 公開読了時間 1 分

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

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

ハッシュテーブルとは

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

Mappings in Solidity Explained by Doug Crescenzi
Source: Mappings in Solidity Explained by Doug Crescenzi

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

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

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

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

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

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

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

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

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

Solidityのarrayは、既知のキーに基づいて値を取得できるマッピングと比較して、データ群を反復処理する場合(例えばforループを使用する場合)に適している。

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

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

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

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

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

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

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

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

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

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

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

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

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

Solidityマッピングの例

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

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

1. ERC20ユーザー残高

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

2. Solidityマッピング bool の例

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

3. メンバーであるかどうか(DAO)

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

このコード例は、2つのSolidity構造体である_ProposalStruct_と_VotedStruct_のフィールドを列挙している。

Solidityの文字列マッピング

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

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

SolidityマッピングのFAQ

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

  1. Solidityマッピングの長さとは何か
  2. Solidityマッピングのデフォルト値とは何か
  3. 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である場合、Solidityコンパイラが生成するgetter関数を使用してアクセスできる。

Background gradient

ブロックチェーンで魔法を生み出す

Alchemyは、最も強力なweb3開発者向けプロダクトとツールを、豊富なリソース、コミュニティ、そして卓越したサポートと組み合わせて提供します。