Remix IDE サンプルコードの解析2

スポンサーリンク

Remix IDEにはデフォルトでSolidityのサンプルコードが3本が格納されています。非常にシンプルなコードですが、Solidityの基礎的な要素が盛り込まれていますので、初心者の方にはとても良い教材となっています。
今回はその2つ目のOwnerコントラクトのソースコードを解析してみます。1つ目のStorageコントラクトについては以下の記事をご覧ください。なお、1つ目で解説した要素についても、記載していますので、必要に応じて読み飛ばしてください。

Remix IDEサンプルコード:Ownerコントラクト

2つ目のOwnerコントラクトのソースコードを解析していきましょう。コードの頭から順に見ていきましょう。

version pragma:コンパイラバージョン

ソースコードの3行目にある “pragma solidity” は、Solidityのコンパイラーバージョンを指定している箇所になります。

pragma solidity >=0.7.0 <0.9.0;

この場合、バージョン0.7.0以上、0.9.0未満のコンパイラーバージョンに対応したソースということを宣言しています。これは、バージョンが上がることにより仕様が変わり、コードが意図した動きをしなくなることを避ける目的があります。

範囲指定ではなく、単一バージョンを指定して書くことも可能です。

pragma solidity ^0.8.12

バージョンの頭に「^」(ハット)が付いている場合は、0.8.12 バージョン固定ということではなく、0.8.12以降で0.8.xx最新のコンパイラーバージョンを指定したことになります。

(参考:Solidity Docs の version pragma解説)

import:別ファイルソースの読み込み

importは別ファイルソースの読み込みを行う指示文です。

ここでは hardhatフォルダ配下の console.solというファイルを読み込んでいます。

import "hardhat/console.sol";

Remix IDE内では、実際にはサンプルコードが格納されている contracts フォルダと同じ default_workspace内の .deps フォルダ内に格納されています。
.deps > npm > hardhat > console.sol

/* */:コメント

/* から */ はコメント行になります。単行のコメントは // でも記載可能です。複数行の場合は、/* から */ の間がコメントになります。

コメントの中に、@dev, @param といった記載がありますが、これは NatSpec(ナットスペック:Ethereum Natural Language Specification Format) と呼ばれる、Solidityにおけるコメント記載の標準ルールのタグになります。NatSpecについてはまた別途ご説明いたします。

    /**
   * @title Owner
   * @dev Set & change owner
   */

(参考:Solidity DocsのNatSpec解説)

contract:コントラクト

“contract” で始まり、波括弧(Curly Brackets)で括られた部分がコントラクト本体になります。contractに続く文字列がコントラクト名称です。コントラクト名称は通常、最初の文字が大文字になります。

contract Owner {

}

address:アドレス型宣言

Ownerコントラクト内で最初に記載されている address は変数の型になります。

address private owner;

ownerという状態変数をaddress型で定義していることになります。このaddressは Ethereumのアドレスを格納する20バイトの領域です。

(参考:Solidity Docsのaddress解説)

owner の前にある private はこの状態変数 ownerのVisibility(視認性、可視性)を定義しています。この関数のアクセスレベルを表しています。privateはこのContract内のみで使用ができます。外部からは見えません。また、継承したContractでも見ることができません。状態変数のVisibilityにはprivateの他に public, internalがあります。internal は private に似ていますが、internalは継承先のContractから見えるということが異なる点になります。
ちなみに、関数のVisibilityにはexternalがありますが、状態変数にはありません。

(参考:Solidity DocsのState Variable Visibility解説)

event:EVMのログ出力

eventはEVM(Ethereum Virtual Machine)へのログ出力機能になります。関数と同様にeventで定義し、実際の呼び出しは emit を使用します。

    // event for EVM logging
    event OwnerSet(address indexed oldOwner, address indexed newOwner);

ここでは OwnerSet という event を定義しています。第1引数、第2引数ともにaddress型の変数を与えています。この OwnerSetをコントラクト内で emit を使用し呼び出すと、引数の値がログに出力されます。

modifier:関数修飾子

modifierは関数に付加することのできるコードをまとめたものです。複数の関数で利用できます。
以下の isOwner では、require の行が本体となっています。この部分が関数に付加されます。
modifier の中には、_(アンダーバー)の記載があります。このアンダーバーの位置に修飾する関数の内容が置き換わります。

    // modifier to check if caller is owner
    modifier isOwner() {
        // If the first argument of 'require' evaluates to 'false', execution terminates and all
        // changes to the state and to Ether balances are reverted.
        // This used to consume all gas in old EVM versions, but not anymore.
        // It is often a good idea to use 'require' to check if functions are called correctly.
        // As a second argument, you can also provide an explanation about what went wrong.
        require(msg.sender == owner, "Caller is not owner");
        _;
    }

modifierは、関数の宣言の最後に付加して使用します。以下の関数changeOwnerでは関数宣言の一番後、丸括弧の前に modifier の isOwner が記述されています。

    function changeOwner(address newOwner) public isOwner {

constructor:deploy時実行コード

constructor は、特殊なコードです。Contract をオンチェーンにdeployするときのみに実行されます。
このOwnerコントラクトの constructor では、主にコンソールロギングにDeployしたアドレスを表示しています。
(参考:Solidity Docsの constructor

    /**
     * @dev Set contract deployer as owner
     */
    constructor() {
        console.log("Owner contract deployed by:", msg.sender);
        owner = msg.sender; // 'msg.sender' is sender of current call, contract deployer for a constructor
        emit OwnerSet(address(0), owner);
    }

function:関数 ー changeOwner

function は関数の定義です。最初の関数は changeOwner という関数名を定義しています。

    function changeOwner(address newOwner) public isOwner {
        emit OwnerSet(owner, newOwner);
        owner = newOwner;
    }

関数名の後に丸括弧で括られている部分は引数になります。この changeOwner 関数は address型の newOwner という一つの引数を持っています。

引数の定義の後にある public は関数のVisibility(視認性、可視性)と呼ばれるものです。この関数のアクセスレベルを表しています。publicは外部からの呼び出しが可能な関数の宣言です。関数のVisibilityには他に external, internal, privateがあります。(参考:Solidity DocsのFunction Visibility)

この changeOwner 関数は、引数の newOwner を受け取り、その値をコントラクト内の状態変数 owner に格納しています。

function:関数 ー getOwner

2つ目の関数 getOwner は引数はありませんが、復帰値を持つ関数です。関数の宣言に returns (address) との記載があり、関数内で、return owner と記載があります。関数が呼び出された時に、コントラクト内の状態変数 owner に格納されている値を返す関数になっています。

    function getOwner() external view returns (address) {
        return owner;
    }

また、この retrieve 関数には external というVisibilityの後に view という記載があります。これは State Mutabilityと呼ばれるもので、状態変数の変更可能性の宣言になります。viewは、「状態変数の参照はするが、変更はしない」という宣言になります。State Mutabilityには他に、pure, payable, nonpayable があります。(参考:Solidity DocsのState Mutability

Ownerコントラクトのまとめ

Remix IDEにデフォルトで格納されているSolidityサンプルコードのひとつである Owner コントラクトの解析を行いました。非常にシンプルですが、コンパイラバージョン、コントラクト、関数、型、コメント等のSolidityコードの基本的な要素が含まれていました。また、constructor, modifier, eventといったSolidityに特徴的な要素もあり、とても参考になるコードです。
Solidity初心者には勉強になりますね。他のSolidityコードも読み解いていきましょう。

コメント

タイトルとURLをコピーしました