[スマートコントラクト・プログラミング言語]Solidityコントラクトの継承

プログラミング

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

Solidityコントラクトの継承について

オブジェクト指向プログラミング言語の最も重要な機能の1つである概念に継承という処理があります。

継承は、プログラムの機能を拡張する方法であり、コードを分離し、依存関係を減らし、既存のコードの再利用性を高めるために使用されています。

Solidityではスマートコントラクト間の継承をサポートしています。複数のコントラクトを1つのコントラクトに継承することができるのです。

他のコントラクトが機能を継承するコントラクトをベースコントラクトと呼び、機能を継承するコントラクトを派生コントラクトと呼びます。

Solidityではこれらのコントラクトのことを、親子コントラクトとも呼んでいます。

Solidity における継承の範囲は、public および internal modifiers にのみ限定されています。

Solidityでの継承機能について、簡単にまとめておきます。

  • 派生コントラクト(子コントラクト)は、状態変数(ステート変数)や内部メソッドなど、プライベートでないすべてのメンバにアクセスすることができる。しかし、これを使うことは許されない。
  • 関数のオーバーライドは、関数のシグネチャが同じであれば可能。出力パラメータが異なる場合、コンパイルに失敗する。
  • スーパーコントラクトの関数を呼び出すには、super キーワードを使用するか、スーパーコントラクト名を使用する。

Solidity は、下記のようなさまざまなタイプの継承をサポートしています。

  1. 単一継承
  2. マルチレベル継承
  3. 階層的継承
  4. 多重継承
  5. 抽象的な継承(Abstract Contract)

単一継承

単一継承とは、ベースとなるコントラクト(親コントラクト)の関数や変数が、1つの派生コントラクト(子コントラクト)にのみ継承されることを言います。

以下は、親コントラクトが子コントラクトに継承され、単一継承をしている例です。

上記コードをコンパイルし、callerコントラクトをDeploy,InheritanceCheck関数を動かすと下記結果が表示されます。

$ decoded output
{
“1”: “uint256: sum 50”
}

2. マルチレベル継承

マルチレベル継承は、単一継承とよく似ていますが、親と子の関係にレベルがある点が異なります。

親から派生した子のコントラクトは、そこから派生したコントラクト(孫コントラクト)に対しても親の機能を継承します。

以下は、ContractのAがBに継承され、コントラクトのBがCに継承されたマルチレベル継承のソースコードです。

上記コードをコンパイルし、callerコントラクトをDeploy,testInheritance関数を動かすと下記結果が表示されます。

$ decoded output
{
“0”: “string: 0xBrokersby 0xMasa”
}

3. 階層的継承

階層型継承とは、親コントラクトが複数の子コントラクトを持つことを指します。

これは主に、共通の機能を異なる場所で使用する場合に使用されています。

親のコントラクトが携帯電話、親のコントラクトを継承した子供の契約がiPhoneとAndroidで枝分かれすると考えるとわかりやすいのではないでしょうか。

以下は、コントラクトAがBに継承され、コントラクトAがCにも別に継承されており、BとCでそれぞれ階層的な継承が行われているソースコードです。

上記コードをコンパイルし、callerコントラクトをDeploy,InheritanceCheck関数を動かすと下記結果が表示されます。

$ decoded output
{
“0”: “uint256: product 200”,
“1”: “uint256: sum 30”
}

4.多重継承

多重継承とは、1つのコントラクトを多くのコントラクトから継承することができことをさします。

親コントラクトは複数の子コントラクトを持つことができ、子コントラクトは複数の親コントラクトを持つことができます。

以下は、コントラクトAがBに継承され、コントラクトCがA、Bを継承している多重継承の例を示したスマートコントラクトコード例です。

上記コードをコンパイルし、callerコントラクトをDeploy,testInheritance関数を動かすと下記結果が表示されます。

$ decoded output
{
“0”: “string: 0xBrokers”,
“1”: “uint256: 1048576”
}

5.抽象的な契約(Abstract Contract)

抽象的な契約とは少なくとも一つの関数を含むが、実装を含まないコントラクトのことを指します。

抽象コントラクトは、子コントラクトの基礎となり、子コントラクトがその機能を継承して利用できるようにします。

Solidity には、抽象コントラクトを確立するための設定はありません。以前までのVersionではcontractの前にabstractをつけることによって明示的に表現していましたが、現在では撤廃されています。

コントラクトに未実装の関数が含まれている場合、それは抽象的なContractとEVMが判断します。

このソースコードでは下記の実装をしています

  • 抽象的な契約Abstract SampleのContractを定義
  • x コントラクトは、Abstract Sampleを継承。
  • 子コントラクトに実装されたすべての抽象関数は、子コントラクトオブジェクトを使用して呼び出されます。

このソースコードをコンパイルしてみましょう。コンパイルは何も問題なく可能です。

しかし、抽象的な契約(Abstract Contract)であるAbstract Sampleをイーサリアムブロックチェーン(EVM)へDeployしようとすると下記の警告が出てDeployすることが出来ない形になります。

EVMデプロイ時のAlert

$deploy AbstractSample
This contract may be abstract, it may not implement an abstract parent’s methods completely or it may not invoke an inherited contract’s constructor correctly.

抽象的なContractであるAbstractSampleを継承したxであれば問題なく、Deploy出来ます。

上記コードをコンパイルし、xコントラクトをDeploy,get関数を動かすと下記結果が表示されます。

$ decoded output
{
“0”: “uint256: sum 30”
}

最後に

今回紹介した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をコピーしました