本文へスキップ
BecomeCoder

Solidityコース · 第5章 発展 ― 継承・トークン・セキュリティ · レッスン20

継承 ― 既存コントラクトを引き継ぐ

ブラウザで完結

導入

あるコントラクトの機能を別のコントラクトが引き継いで拡張するのが 継承(inheritance) です。「所有者だけが操作できる」といった定番機能を毎回書かず、共通の親から受け継ぎます。

説明

is キーワードで親コントラクトを継承します。

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

// 親:所有者の管理機能
contract Ownable {
    address public owner;

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "owner only");
        _;
    }
}

// 子:Ownable を継承して機能を足す
contract Shop is Ownable {
    uint256 public price;

    // 親の onlyOwner をそのまま使える
    function setPrice(uint256 _price) public onlyOwner {
        price = _price;
    }
}
  • contract Shop is OwnableShopOwnable を継承。親の owner / onlyOwner自分のもののように使える
  • 親の internal / public なメンバーは子から使えるが、private は使えない(第2章の可視性表を参照)。
  • 親の関数を子で上書きするときは virtual(親側)と override(子側)を付ける。
graph TB
    O["Ownable(親)<br/>owner / onlyOwner"]
    O --> S["Shop(子)<br/>is Ownable<br/>price / setPrice"]
    O --> T["Token(別の子)<br/>is Ownable"]

実務では、監査済みの安全な実装を集めた OpenZeppelin というライブラリの Ownable などを継承するのが定番です。「車輪の再発明」をせず、実績あるコードを継承して土台にします。

やってみよう

Ownable を一度きちんと作れば、Shop でも Token でも is Ownable するだけで所有者管理が手に入ります。共通機能を親にまとめる設計が、コードの重複とバグを同時に減らすことを実感してみましょう。

実際に動かしてみよう

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

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

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