[DAppsプログラミング言語]SolidityのMapping(配列との違いについて)

プログラミング

スマートコントラクトプログラミング言語であるSolidityのMappingについて記載します。

SolidityのMappingについて

Solidity のマッピングは、他のプログラミング言語におけるハッシュテーブルやディクショナリー機能のように動作します。

SolidityのMappingでは、Key(キー)とValue(値)のペアの形でデータを格納し、スマートコントラクトでは主に一意のイーサリアム・アドレスを関連する値の型に関連付けするために使用されています。

Mappingのルール

  • マッピングは、ストレージのタイプのみを持つことができ、一般的に状態変数に使用されます。
  • マッピングは public とマークすることができます。Solidity は自動的にそのためのgetter関数を作成します。

Mappingの利用例

マッピングの構文は下記のとおりです

マッピングはキーと値(それぞれ事前に定義されたタイプ)のテーブルと言えるかもしれません。

ここで実際のデータ型や変数の例を見てみたいと思います。

上記のマッピングはaddressをKey、uintをデータタイプとしてpointsをマッピングとして宣言しています。

このマッピングを宣言することによって、下記のような空のテーブルを作成した形になります。

address (key) points (value)

実際の値も入れて確認してみましょう。

テーブルを見てみましょう。このような形でデータを持つことになります。

addressをキーにしてsocresのデータを確認することが出来るようになります。

address (key) points (value)
0x5B,,,,eddC4 1000

テーブルとして考えるとわかりやすいですよね。

Mappingのデフォルト値

まだ明示的に値が設定されていないキーに対して、設定した場合はデフォルト値が設定されます。

Solidityのすべてのデータ型には、値が割り当てられていない場合のデフォルト値があります。

「未定義」または「NULL」値の概念は Solidity には存在しませんが、新しく宣言された変数には、その型に依存するデフォルト値が常に存在します。

Solidityのデフォルト値は下記のとおりです。

uint 0
int 0
fixed 0.0
string “”
boolean fakse
enum enumの最初の要素
address 0x0
array 動的配列として設定
mapping 空のマッピングとして設定
struct 構造体で定義された変数のデフォルト値

Mappingを利用するうえで押さえておくべきポイント

Mappingは配列(Array)と非常に似ていると思うかもしれません。

Solidityの配列については下記を参照ください。

[スマートコントラクト・プログラミング]Solidityの配列操作
スマートコントラクトプログラミング言語であるSolidityの配列について記載します。 Solidityの配列 Solidityでの配列は、すべての要素がインデックスと呼ばれる特定の場所を持ち、同じデータ型の要素の固定コレクショ...

実際には配列とは大きく異なり、マッピングには長さが存在しません。

配列は、Indexの最大値を指定したり、動的配列を設定し値を設定したのちに配列の長さが設定されますが、マッピングには長さの概念がありません。

マッピングから値を取り出す場合、その対象の値のKeyを知らなければなりません。

マッピングではKeyを知っている必要があり、上記例でいえばaddressの値を知っていないと、pointsの値は取り出すことは出来ません。

配列ではそのようなことはありませんね。for文などで配列に設定されている長さを指定して、全ての値を取り出し、対象を割り出すことは可能です。

しかし、マッピングではキーを知らなければデータは取り出せません。

一見使いづらいように思いますが、Solidity,ブロックチェーンの世界ではmappingはよく利用されています。

Keyがないと値を取り出せないという特性を活かしスマートコントラクトの相手のアドレス(msg.sender)をmappingのkeyとして値を保持することに利用されているのです。

では、MappingとArray配列どちらを使うべきか?

データに対して反復処理を行う必要がある場合 (たとえば for ループ) は、配列を使用しようするべきです。

データを繰り返し処理する必要がなく、既知のキーに基づいて値を取得するのであれば、マッピングを使用するべきと言えるでしょう。

Solidity では、配列の反復処理は高コストです。あまりにも大きな配列データの反復処理をさせるとトランザクション上のETHやトークンよりもガス代が高額になってしまうこともあり得ます。

もし、Keyを設定することによってデータを管理、利用できるのであればマッピングを使うのが得策と言えるでしょう。データが大きくなりそうであればなおさらです。

マッピングであれば、スマート コントラクト内に値とキーの両方を格納する必要があるため、開発者はキーの配列を作成し、マッピング内の関連値から取得できるデータへの参照として使用することができます。

マッピングのスマートコントラクト利用例

次にSolidity でマッピングがどのように機能するかスマートコントラクトを動かしてみましょう。

このスマートコントラクトでも、addressをKeyとして、Keyの値にmsg.sender(スマートコントラクトを実行したアドレス)を設定させています。

このスマートコントラクトをDeployし、setファンクションにて10を設定して呼び出し、その後getファンクションをCallすると、下記のようにmappingの値が表示されます。

$ decoded output
{
“0”: “uint256: 10”
}

最後に

今回紹介したSolidityの仕様やコードをRemix IDEHardhatで実際に実行やテストをして確認してみましょう。

実際に動かしたり、テストすることで理解が深まるかと思います。

hardhatのインストール手順

Ethereum(イーサリアム)のDApps開発環境Hardhatのインストール手順
Ethereum(イーサリアム)のローカル開発環境であるHardhatのインストール手順を記載します。 Hardhatとは? Hardhatは、Solidityなどで開発したイーサリアムのスマートコントラクト、Dappsをコ...

HardhatでスマートコントラクトのDeploy手順

[Hardhat]SolidityでHello Worldのスマートコントラクトを作成
Solidityを使ってHello Worldを作成してみましょう SolidityでHello World! 前提条件 ・Hardhat デフォルト・フォルダ構成 Hardhatについては下記記事を参照ください。 ...
タイトルとURLをコピーしました