Solidityのstructとは?
執筆者 John Favole
Solidityにはuint(符号なし整数)、bool、_string_など、さまざまな基本データ型がありますが、ブロックチェーン開発者としては、自分で定義できる柔軟なデータ型が必要になることがあります。**struct(構造体)**とは、多様なデータ型の変数を1つの変数、つまりカスタムメイドの型にまとめることができるSolidityのデータ構造の形式です。
この記事ではSolidityにおけるstructを紹介し、それが何をするものか、どう動作するかを説明します。最後に、structを使ってより堅牢なスマートコントラクトを作る方法を解説します。
Solidityのstructとは
structとは、多様なデータ型の変数を1つの変数、つまりカスタムメイドの型にまとめることができる、Solidityの独創的なデータ構造の形式です。 データ型がstructにまとめられると、struct名はその中に含まれる変数のサブセットを表すようになります。
structを、異なる種類のオブジェクトが入ったコンテナだと考えてみてください。コンテナを動かすと、その中身のアイテムもすべて一緒に動きます。同様に、Solidity開発者がstructの名前を宣言または呼び出すと、そのstructは内部のデータ型に応じて反応します。
以下はSolidityのstructの例です:
上記のstructの例には、address creator、string name、address users、uint amountという変数が含まれています。
Solidityのstructのコード例
このセクションでは、Solidityでstructを定義・作成するためのサンプルコードを紹介します。また、struct宣言に使える2つの方法についても説明します。最後に、structのインポートと初期化の方法を紹介します。
Solidityでstructを定義・作成する方法
structのコードは、JavaScriptにおけるオブジェクト宣言の書き方によく似ています。見た目はよく似ていますが、構文の動作は異なります。Solidityのstructは常に以下の形式になります。
Solidityのstructの定義・作成方法は以下の通りです:
- structキーワードを書いてstructを作成します。これにより、後に続く型がカスタム型であることをSolidityコンパイラに伝えます
- structに名前を付けます。この名前が、struct内にまとめられた変数と対応関係を持つことになります
- 波括弧を使用します。角括弧や丸括弧など他の種類の括弧ではコンパイルできません
波括弧を使わないと、Remix上で以下のようなParserErrorメッセージが表示されます。

- データ型を、それに対応する変数とともに宣言します
上記の例では、string theWord、uint theFigure、bool polarDataがそれに当たります。ここで、structのサブセットを宣言することになります。スマートコントラクト内でstructが宣言された後は、コード内で後からそのstructの名前を呼び出せるようになります。
開発者向けTips:
- 波括弧のみを使用すること
- structの各メンバーはセミコロンで終えること
- そのクラスに合わない変数を宣言・入力すると、Solidityはエラーを出す
- スマートコントラクトには複数のstructを含めることができ、それぞれキーワードによって区別される
Solidityのstructを宣言する方法
structを宣言できる場所は2つあります:コントラクトの内側、またはコントラクトの外側です。どちらの場所にSolidityのstructを宣言すべきかは、何をしたいかによって決まります。struct宣言の2つの選択肢を見ていきましょう。
コントラクトの外側でstructを宣言する
上記の例では、floorOverlay structはスマートコントラクトの外側で宣言されており、コードベース内のすべてのコントラクトから呼び出すことができます。特定のコントラクト専用のstructだけを持たせるのではなく、すべてのコントラクトでより汎用的に使えるstructを作りたい場合は、スマートコントラクトの外側でstructを宣言するのが最善です。
さらに、複数のスマートコントラクトで同じstructのコレクションを利用したい場合は、各スマートコントラクトごとに個別にstructを作成するのではなく、_pragma_の直後に宣言してください。
コントラクトの内側でstructを宣言する
carpet structはスマートコントラクトの内側にあり、その結果、このstructの機能は現在のコントラクトに限定されます。他のコントラクトからその名前を呼び出すことはできません。
Solidityのstructをインポートする方法
structはあるスマートコントラクトから別のスマートコントラクトへインポートできるため、開発者は時間を節約し、再利用可能なコードを作成できます。structをインポートする方法を示すために、以下に2つのスマートコントラクトを示します。1つはstructが作成されているコントラクト、もう1つはそれがインポートされるコントラクトです。
インポート時に避けるべきエラーがあります。2つ目のコントラクトの名前は、インポートしたいstructの名前と一致させる必要があります。そうしないと、Solidityコンパイラがそれを識別できず、バグが発生します。
Solidityでstructを初期化する方法
structを宣言・作成しても、さまざまなSolidityの関数でそれを使うには、何らかの初期値を割り当てる必要があります。structを初期化する方法は3通りあります:(i) キーバリューペア方式、(ii) 定義してから更新する方式、(iii) パラメータを括弧で囲む方式です。
1. キーバリューペア方式
この方法では、struct内の各キーの型を選び、それぞれに値を割り当てます。
この方式の構文は厳密ではなく、struct内の型の順序に従わなくても構いません。
2. 定義してから更新する方式
この初期化方式の構文では、まずstructを格納するための変数を入力し、その後、その変数を使ってstructの各メンバーにアクセスし、名前を付けます。以下のコードがその例です:
ただし、ほとんどの開発者はこの方法を使いません。コードが長くなるためです。
3. パラメータを括弧で囲む方式
この方法を使う場合、structの名前を呼び出し、そのメモリを格納した上で、structのメンバーに順番通りに値を与える必要があります。以下がその例です:
ここでは、「measles」がこの初期化を格納する変数であり、struct内で定められたパラメータもあわせて宣言しています。Solidityコンパイラが識別できるように、括弧内の宣言名は必ずアポストロフィで囲むことを忘れないでください。
Solidityのstructのユースケース
このセクションでは、コントラクト内のユーザー情報を追跡するためのSolidityの活用例を紹介します。このユースケースではstructがマッピングされます。
Solidityでstructをマッピングできるか
Solidityでは、structを値の型としてマッピングできるため、structの任意のメンバーに関する情報を追跡できます。 例えば、以下のコードを見てください:
このコントラクトでは、特定のDAOにおける各メンバーの詳細が分類されています。ここでは2つのマッピングを作成しました。1つはシンプルなもので、もう1つはネストされたものです。
シンプルなマッピングでは、各メンバーのアドレスをstructにマッピングし、特定のメンバーを見つけやすくしています。さらに、ネストされたマッピングにより、DAOメンバーのアドレスと、投票済みかどうかを追跡しやすくしています。
マッピングは常にキー型 => 値型という構文になるため、structは必ず値型として宣言する必要があり、キー型として宣言してはいけません。そうしないとエラーが発生します。

まとめ — Solidityにおけるstructの本質とは
Solidityのstructを使うと、開発者は自分が作ろうとしているものに合わせたカスタム型を作成できます。このカスタム型は、関連するデータ型をまとめて保持するコンテナのようなものです。structについてさらに学びたい方は、Alchemy UniversityのSolidityブートキャンプにぜひご参加ください!
関連する概要

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


