本文へスキップ
BecomeCoder

Solidityコース · 第3章 値とデータ構造 ― address・mapping・struct · レッスン14

struct と enum ― 自分で型を作る

ブラウザで完結

導入

複数の値を1つにまとめた「自作の型」が struct(構造体)、決まった選択肢を名前で表すのが enum(列挙型) です。データを意味のあるかたまりで扱えるようになります。

説明

「ユーザー1人分の情報」を struct にまとめ、状態を enum で表してみます。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract Registry {
    // 状態の選択肢に名前を付ける
    enum Status { Pending, Active, Banned }

    // 複数の値を1まとめにした自作の型
    struct User {
        string  name;
        uint256 age;
        Status  status;
    }

    // アドレス → ユーザー情報 の対応表
    mapping(address => User) public users;

    function register(string memory _name, uint256 _age) public {
        users[msg.sender] = User({
            name: _name,
            age: _age,
            status: Status.Active
        });
    }
}
  • struct User { ... } … 名前・年齢・状態を1つの型にまとめる。users[addr].name のように . で各要素にアクセス。
  • enum Status { Pending, Active, Banned } … 状態を分かりやすい名前で表す。内部では 0, 1, 2 の整数だが、コードでは Status.Active と書けて読みやすく、間違いも防げる。
  • mapping(address => User) … mapping・struct・enum を組み合わせた、実務で頻出の形。
graph TB
    M["mapping(address => User)"]
    M --> U["User 構造体"]
    U --> N["name: string"]
    U --> A["age: uint256"]
    U --> S["status: enum<br/>Pending / Active / Banned"]

struct・enum・mapping・配列を組み合わせると、「誰が・どんな状態で・何を持っているか」を表現できます。これがコントラクトのデータ設計の基本パターンです。

やってみよう

enum を使わずに uint256 status(0=保留, 1=有効…)と書くこともできますが、Status.Active のほうが意味が一目で分かり、無効な値を防げます。「マジックナンバーを名前にする」enum の利点を意識してみましょう。

実際に動かしてみよう

下のエディタのコントラクトを「コンパイル & デプロイ」すると、ブラウザ内で本物のSolidityコンパイラ(solc)がコンパイルし、EVM(@ethereumjs)にデプロイされます。デプロイ後は public な関数がボタンになって並ぶので、引数を入れて呼び出すと戻り値・イベント・require のエラー(revert理由)まで確認できます。本文のコントラクトを書き換えて動きを試しながら進めましょう(コンパイラ本体は初回だけ読み込みに数秒かかります)。

Solidity — ブラウザ内でコンパイル & 実行

ブラウザ内で本物のSolidityコンパイラ(solc)とEVM(@ethereumjs)を動かす環境を読み込みます(コンパイラ本体は初回のコンパイル時に読み込むため、最初の実行だけ数秒かかります)。
スクロールして表示された時点でも自動で読み込まれます。