スマートコントラクトプログラミング言語であるSolidityの関数修飾子であるview,pureについて記載します。
Solidityの関数修飾子 viewとpureについて
基本的な関数の定義、構文については下記記事を参照ください。

今回は、関数を修飾する関数修飾子であるviewとpureについて記載します。
View関数
View関数は、状態を変更しないことを保証します。
もし、関数内に次のような記述があると、状態を変更しているとみなされ、コンパイラはそのような場合にエラーを投げます。
- 状態変数の変更
- イベントの発行
- 他のコントラクトの作成
- 自己破壊の使用
- コールによる Ether の送信
- viewまたはpureと定義されていない関数を呼び出すこと
- 低レベルコールの使用
- 特定のオペコードを含むインラインアセンブリの使用
デフォルトでは、getメソッドはview関数です。
以下の例では、2 つの符号なし整数の積と和を計算するview関数を定義しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.4.16 <0.9.0; contract ViewSample{ //ステート変数を定義 uint number1 = 1; uint number2 = 2; //2つの数値の積と和を計算するビュー関数を定義する function get() public view returns(uint product, uint sum){ //ステート変数と同じ変数名だが、関数内のローカル変数として宣言されている為、view関数修飾子が付いていても設定可 uint number1 = 10; uint number2 = 20; product = number1 * number2; sum = number1 + number2; } } |
上記をview関数修飾子が付いたget関数を実行すると下記が表示されます
上記コードを一部改変してみましょう。
get関数内のnumber1とnumber2の型指定(unit)を削除してみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.4.16 <0.9.0; contract ViewSample2{ //ステート変数を定義 uint number1 = 1; uint number2 = 2; //2つの数値の積と和を計算するビュー関数を定義する function get() public view returns(uint product, uint sum){ //ステート変数と同じ変数名で定義されており、ステートの変数を変更しようとしているため、ここでエラー number1 = 10; number2 = 20; product = number1 * number2; sum = number1 + number2; } } |
上記コードは下記のコンパイルエラーが表示され、実行できません。
view関数修飾子が付いており、ステート変数の値を見に行き且設定してしまっているためです。
view関数修飾子を外せば、ステート変数も変更できる通常の関数になるため、ステート変数を変更したい場合は、viewを外す必要があります。
もしくは、状態変数を参照するのみにして他の変数をget関数内で宣言し、その変数に代入して使用する必要があります。
Pure関数
pure関数は、状態を読み取ったり変更したりしないことを保証します。
もし関数内に次のような記述があれば、状態を読み取るものとみなされ、コンパイラはそのような場合にエラーを投げます。
- 状態変数の読み込み
- address(this).balance または <address>.balance にアクセスする。
- block、tx、msgの特殊変数へのアクセス(msg.sigとmsg.dataは読み込み可能)。
- pureでない関数を呼び出すこと。
- 特定のオペコードを含むインラインアセンブリの使用。
pure関数は、revert() および require() 関数を使用して、エラーが発生した場合に潜在的な状態の変化を戻すことができます。
以下の、Pure関数を使用した例をご覧ください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.4.16 <0.9.0; contract PureSample{ //ステート変数を定義 uint number1 = 1; uint number2 = 2; //2つの数値の積と和を計算するPure関数を定義する function get() public pure returns(uint product, uint sum){ //ステート変数と同じ変数名だが、関数内のローカル変数として宣言されている為、pure関数修飾子が付いていても設定可 uint number1 = 10; uint number2 = 20; product = number1 * number2; sum = number1 + number2; } } |
上記コードを実行すると下記が表示されます。
上記コードを一部改変してみましょう。
get関数内のnumber1を参照する形に変更しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.4.16 <0.9.0; contract PureSample2{ //ステート変数を定義 uint number1 = 1; uint number2 = 2; //2つの数値の積と和を計算するPure関数を定義する function get() public pure returns(uint product, uint sum){ //ステート変数number1を参照。pure関数は状態変数の参照も不可のため、ここでエラーが発生する uint number2 = number1 + 1; product = number1 * number2; sum = number1 + number2; } } |
上記コードは下記のコンパイルエラーが表示され、実行できません。
pure関数のため、状態変数の参照が出来ないからです。
view関数であればエラーなく利用可能なため、エラーメッセージにもviewを使うように推奨するメッセージが出ています。
pureとviewの違い
pureとviewの関数修飾子を紹介しましたが、機能としては非常に似ていると思います。
どちらも読み取り専用の関数修飾子のように思いますが、実際には下記の違いがあります。
ここで一度整理したいと思います。
view関数 | pure関数 |
ストレージの状態を一切変更しない。
しかし、それを「見る」(参照する)ことはできます。 |
pureはviewよりさらに厳しい。
ストレージの状態を読み出すことさえしないことを示します。 |
同じコントラクト内にviewとpureの関数を宣言したスマートコントラクトソースコード例はこちらです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; contract ViewAndPure { uint public x = 1; // Promise not to modify the state. function addToX(uint y) public view returns (uint) { return x + y; } // Promise not to modify or read from the state. function add(uint i, uint j) public pure returns (uint) { return i + j; } } |
コンパイルして2つの関数を呼び出すと下記が表示されます
pure関数とは、同じ入力が与えられれば常に同じ出力を返す関数です。
しかし、コントラクトの状態は、ユーザーとの対話によって変化し続けます。
ですから、もし関数に引数として状態変数を渡すと、状態が変化しているため、その関数はpureではなくなるため、pure関数はステートにアクセスできないのです。
またイーサリアムブロックチェーン上でスマートコントラクトを利用するうえで覚えておくべき重要なことがあります。
viewやpure関数を外部から呼び出す場合、ガス料金はかかりません。
しかし、内部で他の関数から呼び出された場合は、ガス代がかかるのです。
スマートコントラクトを動かす場合、ガス代は致命的な問題になりかねないのでしっかりと把握してviewとpureの関数を使用するにしましょう。
最後に
今回紹介したSolidityの仕様やコードをRemix IDEやHardhatで実際に実行やテストをして確認してみましょう。
実際に動かしたり、テストすることで理解が深まるかと思います。
hardhatのインストール手順

HardhatでスマートコントラクトのDeploy手順
