day13. Solidity基本文法 – 継承/インスタンス化 –

Solidityで他のコントラクトの機能を利用するには、2つの方法があります。このチュートリアルでは、継承、インスタンス化の2つの方法について解説します。

Solidityで他のコントラクトの機能を利用するには、2つの方法があります。このチュートリアルでは、継承、インスタンス化の2つの方法について解説します。

TOC

継承

継承とは2つのコントラクトに親子関係を持たせ、親の機能を子に引き継がせることを言います。つまり、継承を使用することで、コントラクト間で機能を共有することができます。
継承により、親コントラクトの関数や変数を子コントラクトで使用することができます。

day7では、次に記載のコードがありましたが、ここでは継承が使われています。MyToken is ERC20という一文がありますが、これはMyTokenERC20の機能を継承している(ERC20が親、MyTokenが子である)ということを定義しているものです。

ERC20には様々な機能が定義されていますが、そのうちの一つとして、トークンを発行する(英語で”mint”)という機能があります。それをERC20で定義しているのが、_mint関数になります。この関数は引数として呼び出した人のアドレスと発行量を取りますが、これは、_mint関数を呼び出した人に対して、引数initialSupplyで与えられた数字単位分のトークンを発行するということを行っています。
この機能は、MyTokenでも利用可能です(なので、MyToken内に、_mint関数に関する記述がないにも関わらず、実際には呼ぶことができているというわけです)。

Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {
    constructor(string memory _name, string memory _symbol, uint256 initialSupply) ERC20(_name, _symbol) {
        _mint(msg.sender, initialSupply);
    }
}

ERCは、Ethereum Request for Commentsの略で、Ethereumの仕様について提案したドキュメントです。ERC20はトークンの標準について定めており、トークンの送受信や残高の確認などの基本的な機能を定義しています。他にもERC721(NFT)、ERC1155(異なる種類の複数のトークンを管理する仕組み)などがよく使われる標準です。
ERC20の実装例として、openzeppelinというライブラリー群のERC20.solがあります(上述の例でimportしているもの)。こちらのリンク先で実際に利用可能な関数を確認することができ、その中に_mint関数が含まれていることがわかります。
openzepplinは最もよく使われるライブラリー群です。

コンストラクター

constructorは、インスタンス化される際に初期に実行される処理を定義しておくブロックです。つまり、インスタンス化される際の初期処理のことです(インスタンス化とは、後述するように実際に変数として定義・利用され、実体化されることを言います)。

上述の例では、constructorはインプットとなる3つの変数(トークンの名称、シンボル、発行量)を引数としてもち、_mint関数を呼んでいます。

※名称、シンボルはEthereumを例にすると、それぞれEtherとETHになります。シンボルとは略称のアルファベットのことで、通常3文字です。

コントラクトを利用する際には、constructorで定義した引数を渡してやる必要があります。仮に上記のMyTokenコントラクトを変数として利用したい場合、前述の3つの変数を渡すことになります。
次のコードは、実際にコントラクトを利用する際の定義の例です。上述の例で定義したMyToken型の変数を定義しています。

下記の例のように、コントラクトを変数として定義する場合には、<コントラクト名> <変数名> = new <コントラクト名>(constructorの定義と対になる引数)という構文で定義することができます。

Solidity
import "path/to/contract/MyToken.sol"; //MyToken.solの置かれている場所のパス名を記載する

contract TokenVillageToken {
  MyToken tokenVillage = new MyToken("TokenVillageToken", "TVT", 1000000000000000000);
  // <コントラクト名> <変数名> = new <コントラクト名>(constructorの定義と対になる引数)

  function getName() public view returns (string memory) {
    return tokenVillage.name(); // name()関数はERC20で定義されている関数でトークンの名前を返す
  }

  function getSymbol() public view returns (string memory) {
    return tokenVillage.symbol(); // symbole()関数はERC20で定義されている関数でトークンのシンボルを返す
  }

}

MyToken型の変数が定義される際に、constructor内の処理が実行されます。この例の場合、”TokenVillageToken”という名称かつ”TVT”というシンボルのトークンが、1000000000000000000単位分発行される(_mint)ということになります。

コントラクトのインスタンス化と呼び出し

インスタンス化

インスタンス化とは、コントラクト(設計図)からインスタンス(実体)を生成する行為のことです。他のコントラクトを自分が実装しているコントラクトで使用したい場合、まずそのコントラクトをインスタンス化します。
インスタンス化することによって、他のコントラクトの関数や変数にアクセスして使用することができます。

次の例は、前述の例で登場したERC20型の変数newTokenを定義し、コンストラクターで初期化される際に、newTokenの変数にすでにデプロイ済みのトークンのアドレスを与えています。こうすることで、デプロイ済みのコントラクトをこのコントラクトの中で使うことができます(デプロイ済み=実体(インスタンス)を伴っている)。

<変数> = <使いたいコントラクト>(コントラクトのアドレス)という構文で呼び出すことができます。

Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract NewToken {
  ERC20 public newToken;

  constructor(address _newTokenAddress) {
      newToken = ERC20(_newTokenAddress);
  }

  function getNewTokenName() public view returns (string memory) {
      return newToken.name();
  }
}

次の画像は、NewTokenコントラクトのデプロイ例です。”Deploy”ボタンの右にあるテキストボックスにすでにデプロイ済みのERC20型のコントラクトのアドレス0xE73…のアドレスを入力して、デプロイします。すると、NewTokenがデプロイされます。ここでgetNewTokenNameを押すとすでにデプロイ済みのトークンの名前(TokenVillageToken)が表示されます。

NewTokenコントラクトをデプロイする際の例です。デプロイの横にあるテキストボックスにすでにデプロイ済みのERC20型のコントラクトのアドレス0xE73...のアドレスを入力して、デプロイします。すると、NewTokenがデプロイされます。ここでgetNewTokenNameを押すとすでにデプロイ済みのトークンの名前が表示されます。

インスタンス化を車に例えると、車の設計図がコントラクトで、工場のラインで製造された車がインスタンスになります。Solidityの場合、コントラクトを変数として定義し、利用すると、それはインスタンス化して使用しているということになります。アドレスを与えるということは、すでにデプロイされている(=アドレスを持っている)コントラクトを呼び出す、ということになります。
※ インスタンスのことをオブジェクトとも呼びます。この2つは基本的には同義です。

ご意見をお聞かせください!

web3チュートリアルシリーズについてのご意見を是非お聞かせください。

この記事、または、web3チュートリアル全体について、是非、あなたのご意見をお聞かせください。
アンケートはこちらからご回答いただけます。

無料相談承ります

ITの専門家が無料相談を受け付けます。web3以外のテーマでもOKです。

オンラインでの無料相談を承っています。ご希望の方は、お問い合わせフォームよりご連絡ください。
ITの専門家があなたのご質問にお答えいたします。

Let's share this post !

Author of this article

After joining IBM in 2004, the author gained extensive experience in developing and maintaining distributed systems, primarily web-based, as an engineer and PM. Later, he founded his own company, designing and developing mobile applications and backend services. He is currently leading a Tech team at a venture company specializing in robo-advisory.

Comments

To comment

CAPTCHA


TOC