Solidityの関数修飾子pure,viewの挙動の違いを確認してみる

2021.09.07

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Solidityの学習を始めたて状態です。

関数につけれる修飾子であるpureviewがまだまだごっちゃになっているので整理しようと思います。

※ Solidityのバージョンを0.8.7にして試していきます

pure修飾子

ドキュメントの説明

Functions can be declared pure in which case they promise not to read from or modify the state.

pureを宣言すると、関数は状態を読み取ったり変更したりしない

引数で受け取った値は使用できる。

例) 引数で受け取った数字を足す

contract MyContract {
    uint hoge = 3;
    
    function add(uint x, uint y) public pure returns(uint){
        return x + y;
    }
}

実行結果、10と20を与えて足したので30が返ってきました

例) ダメなやつ

インスタンス変数であるhogeを読み込んでいるのでコンパイルでエラーしました。

contract MyContract {
    uint hoge = 3;
    
    function add(uint x, uint y) public pure returns(uint){
        return x + y + hoge;
    }
}

状態を読み込んでるからviewを使えと、私はpureなんだと。

contract MyContract {
    uint hoge = 3;
    
    function add(uint x, uint y) public pure returns(uint){
        hoge = x + y;
        return hoge;
    }
}

こちらも書き込んでいるからコンパイルでエラーとなりました。

Gasの消費

Cost only applies when called by a contract とあるので、同じコントラクト内で呼ばれた時に消費するとのことです(外から呼ばれると消費しない)。

view修飾子

ドキュメントの説明

Functions can be declared view in which case they promise not to modify the state.

viewを宣言すると、関数は状態を変更しない

読み込みは可能。

例) 引数で受け取った数字を足す

contract MyContract {
    uint hoge = 3;
    
    function addHogeByX(uint x) public view returns(uint result) {
        result = hoge + x;
        return result;
    }
}

インスタンス変数と引数で受け取った値を足して返却

5を引数で与えたので、8が返ってきましたね。

例) ダメなやつ

インスタンス変数のhogeを書き換えたらコンパイルでエラーになりました。

contract MyContract {
    uint hoge = 3;
    
    function addHogeByX(uint x) public view returns(uint) {
        hoge += x;
        return hoge;
    }
}

viewで宣言しているけど状態を変更しているよと

Gasの消費

Cost only applies when called by a contract とあるので、同じコントラクト内で呼ばれた時に消費するとのことです(外から呼ばれると消費しない)。

まとめ

pure: インスタンス変数(storage)の読み込み、書き込みの両方不可能で、引数で受け取った値は読み書き可能。

view: インスタンス変数(storage)の読み込みは可能、書き込みは不可。

きちんと宣言することで変数の状態を保証できるのでやったほうがいいなと感じています。

参考