こんにちは、エンジニアのオオバです。

Remix IDEというSolidityの統合環境でSolidityの学習を進めています。
環境構築方法はコチラをご覧ください👇

ここから本題。

Solidityでプログラミングしててviewpureという修飾子に出会います。
これらは関数修飾子と呼ばれますが、その違いを理解していきます。

※本記事はSolidityバージョン0.8.4を使用しています

→11万文字で徹底解説した「DOTweenの教科書」Unityアニメーションの超効率化ツールはこちら

参照スコープの違いで使い分ける

関数修飾子viewpureはその関数内で参照する変数のスコープによって使い分けます。

具体的なコードを見ていきます。

関数修飾子viewの場合

インスタンス変数としてfooviewTest関数内で使用しています。

// SPDX-License-Identifier: GPL-3.0  
pragma solidity >=0.7.0 <0.9.0;  

contract ViewAndPureTest {  

    uint8 foo = 3;  

    function viewTest() public view returns(uint8) {  
        return foo;  
    }
}

この場合viewをつけておく必要があります。

もし以下👇のようにpureに変更するとどうなるでしょうか。

function viewTest() public pure returns(uint8) {  
    return foo;  
}

このようにコンパイルエラーになります。

TypeError: Function declared as pure, but this expression (potentially)  
reads from the environment or state and thus requires "view".  

変数を書き換えない制限

viewにはもう一つ制限があります。
参照したインスタンス変数を書き換えてはいけません。

function viewTest() public view returns(uint8) {  
    // fooをインクリメントするとコンパイルエラー  
    foo += 1;  
    return foo;  
}

👆関数内でインスタンス変数の変更(状態変更)をしてはいけません。

TypeError: Function declared as view, but this expression (potentially)  
modifies the state and thus requires non-payable (the default) or payable.  

このようなコンパイルエラーが出力されます。

関数修飾子view関数の中で関数外の変数にアクセス且つその変数を変更しない場合に記述するということになります。

関数修飾子pureの場合

さきほどのviewの説明でほとんど説明してしまいましたが、
pureの使い所はその関数がローカル変数のみにアクセスしている場合です。

// SPDX-License-Identifier: GPL-3.0  
pragma solidity >=0.7.0 <0.9.0;  

contract ViewAndPureTest {  
    function pureTest(uint8 a, uint8 b) public pure returns(uint8){  
        return a * b;  
    }
}

このようにpureTest関数がローカル変数abのみ参照している場合pureを指定します。

しかし先ほどのviewのサンプルとは違うところがあります。
👆の例でpureをviewに変更してもコンパイルは通り実行もできます。

Warning: Function state mutability can be restricted to pure  

コンパイラからこのような警告が出力されますので素直にpureを使いましょう。

まとめ

関数修飾子のviewpureの違いを学習してきました。
普段使っているC#と比べるとSolidityは使っている変数スコープを、
厳格に宣言する必要があります。

またviewを宣言すると参照した変数の状態保持が保証されます。

viewやpureを宣言するのが面倒くさそうに感じるかもしませんが、
参照スコープ・状態保持の保障をコンパイル前に設定できる言語仕様は個人的に好きです。

チーム開発する上でのプロダクトの保守に役立ちそうだなと感じました。

引き続きSolidityの学習を進めていこうと思います。

オススメ記事
検証環境
参考サイト