🌊

Solidity基礎学習4日目(Constructor, メッセージングアプリケーション)

に公開

Solidity基礎学習 - Constructorとメッセージングアプリケーション

日付: 2025年8月17日
学習内容: コンストラクタと実用的なメッセージングアプリケーションの作成について

1. Constructor(コンストラクタ)の学習

008_Constructor.solの概要

スマートコントラクトのコンストラクタについて学習します。コンストラクタは、コントラクトがデプロイされる際に一度だけ実行される特殊な関数です。

重要なポイント

コンストラクタの基本概念

contract ExampleConstructor { 
    address public myAddress;
    
    // コンストラクタはデプロイ時に一度だけ呼び出される特殊な関数
    // 引数を受け取ることができ、public/privateなどの指定はしない
    constructor(address _someAddress) {
        myAddress = _someAddress;
    }
}

コンストラクタの特徴:

  • デプロイ時に一度だけ実行される
  • 引数を受け取ることができる
  • アクセス修飾子(public、private等)は指定しない
  • 初期化処理に使用される

コンストラクタの活用パターン

パターン1: デプロイ時のアドレス設定

constructor(address _someAddress) {
    myAddress = _someAddress;
}

パターン2: デプロイ者のアドレスを直接設定

// デプロイした自分のアドレスをmyAddressに割り当てる場合
address public myAddress = msg.sender;

パターン3: 後から変更可能な設計

function setMyAddress(address _myAddress) public {
    myAddress = _myAddress;
}

function setMyAddressToMsgSender() public {
    myAddress = msg.sender;
}

重要なポイント:

  • コンストラクタは初期化専用
  • デプロイ後に呼び出すことができない
  • 引数を通じて柔軟な初期化が可能
  • セキュリティを考慮した設計が重要

2. 実用的なメッセージングアプリケーション

009_TheBlockchainMessenger.solの概要

これまで学習した概念を総合的に活用して、ブロックチェーン上でメッセージを保存・更新できるアプリケーションを作成しました。

アプリケーションの機能

基本機能

contract BlockchainMessageApp {
    uint public changeCounter;        // メッセージ更新回数のカウンター
    address public owner;            // アプリケーションの所有者
    string public theMessage;        // 保存されるメッセージ
    
    constructor() {
        owner = msg.sender;          // デプロイ者を所有者として設定
    }
}

主要な状態変数:

  • changeCounter: メッセージが更新された回数を追跡
  • owner: アプリケーションの管理者アドレス
  • theMessage: ブロックチェーン上に保存されるメッセージ

メッセージ更新機能

function updateTheMessage(string memory _newMessage) public {
    if(msg.sender == owner) {        // 所有者のみが更新可能
        theMessage = _newMessage;    // 新しいメッセージを保存
        changeCounter++;             // 更新回数をインクリメント
    }
}

セキュリティ機能:

  • 所有者チェック: msg.sender == ownerで権限を確認
  • 更新回数追跡: 変更履歴を透明性を持って記録
  • 権限管理: 所有者以外はメッセージを変更できない

学習した概念の統合

Address型の活用

  • address public owner: 所有者のアドレスを保存
  • msg.sender: 関数呼び出し元のアドレスを取得

MsgSenderの活用

  • コンストラクタでデプロイ者を所有者として設定
  • 関数内で権限チェックに使用

関数の種類

  • Writing function: updateTheMessageで状態を変更
  • View function: 状態変数の読み取り(自動的にview関数として動作)

3. 実装のポイント

セキュリティ設計

// 所有者のみが実行可能な関数
function updateTheMessage(string memory _newMessage) public {
    require(msg.sender == owner, "Only owner can update message");
    theMessage = _newMessage;
    changeCounter++;
}

セキュリティの考慮点:

  • 権限チェック: 所有者以外の操作を防ぐ
  • 入力検証: 適切なメッセージ内容の確認
  • 透明性: 更新回数を記録して監査可能にする

ガスコストの最適化

  • 状態変数の効率的な使用
  • 不要な計算の回避
  • 適切な関数設計

4. 実用的な応用

拡張可能な機能

contract EnhancedMessageApp {
    uint public changeCounter;
    address public owner;
    string public theMessage;
    mapping(address => bool) public authorizedUsers;
    
    constructor() {
        owner = msg.sender;
    }
    
    modifier onlyOwner() {
        require(msg.sender == owner, "Only owner allowed");
        _;
    }
    
    modifier onlyAuthorized() {
        require(msg.sender == owner || authorizedUsers[msg.sender], "Not authorized");
        _;
    }
    
    function addAuthorizedUser(address _user) public onlyOwner {
        authorizedUsers[_user] = true;
    }
    
    function updateMessage(string memory _newMessage) public onlyAuthorized {
        theMessage = _newMessage;
        changeCounter++;
    }
}

拡張機能:

  • 複数ユーザー権限: 承認されたユーザーもメッセージ更新可能
  • 修飾子の活用: コードの再利用性と可読性の向上
  • 柔軟な権限管理: 所有者が権限を動的に管理

5. 学習の成果

習得した概念

  1. コンストラクタ: 初期化処理の実装方法
  2. 権限管理: 所有者ベースのアクセス制御
  3. 状態管理: 複数の状態変数の連携
  4. セキュリティ: 適切な権限チェックの実装
  5. 実用的なアプリケーション: 学習内容の統合

実装スキル

  • スマートコントラクトの設計能力
  • セキュリティを考慮したコーディング
  • 状態変数の効率的な管理
  • 権限システムの実装

参考:

Discussion