Solidityにおける`view`関数と`pure`関数の違いは何ですか?
はい、もちろんです。Solidityにおけるview
とpure
についてお話しましょう。この二つは、実はとても区別しやすいものです。
view
とpure
の違い:一つは見るだけ、もう一つは見ることもない
レストランに入った状況を想像してみてください。
view
関数はメニューを見ているようなものです。メニュー上のすべての料理、価格、説明を確認できます(コントラクトの状態を読み取ります)。しかし、厨房に入って自分でメニューを修正することはできません(コントラクトの状態を変更することはできません)。メニューを見終えても、レストラン自体には何も変化がありません。pure
関数は、自分で持ってきた電卓のようなものです。2 + 3 = 5
のように、それを使って計算します。この計算プロセスは、レストランのメニューに全く依存せず(コントラクトの状態を読み取らず)、もちろんメニューを変更することもありません(コントラクトの状態を変更しません)。それはあなたが入力した数字にのみ関係します。
それでは、詳しく見ていきましょう。
view
関数(読み取り専用関数)
これは「読み取り専用」または「オブザーバー」関数として理解できます。
- 約束:私はコントラクト内のいかなるデータも変更しないことを保証します。
- できること:コントラクトの状態変数を読み取ることができます。例えば、コントラクトに
owner
が誰であるか、またはERC20トークンの総供給量totalSupply
がどれくらいかが記録されている場合、view
関数はこれらの情報を読み取って教えてくれます。 - できないこと:いかなる状態変数も変更できません(例:
owner = newAddress
は不可)。イベントを発行すること(emit
)もできませんし、状態を変更する可能性のある他の関数を呼び出すこともできません。
簡単なコード例:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract SimpleStorage {
uint256 public myNumber = 42; // これは状態変数です
// この関数は状態変数 myNumber の値を読み取ります
// 「見る」だけで「変更」しないので、view です
function getMyNumber() public view returns (uint256) {
return myNumber;
}
}
この例では、getMyNumber()
は単にmyNumber
の値を読み取って返すだけで、何も変更しません。そのため、view
としてマークします。
pure
関数(純粋関数)
こちらはより厳格で、「純粋な計算関数」と呼ぶことができます。
- 約束:私はコントラクトデータを変更しないだけでなく、参照すら行いません。
- できること:関数呼び出し時に渡された引数、または関数内部で定義されたローカル変数のみを使用して計算を行い、結果を返します。コントラクトのストレージ状態からは完全に隔離されています。
- できないこと:
view
関数ができないことはすべてできませんし、さらにコントラクトの状態変数を読み取ることもできません。
簡単なコード例:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract SimpleCalculator {
// この関数は入力された a と b のみに依存します
// コントラクト自体の状態とは全く関係ないので、pure です
function add(uint256 a, uint256 b) public pure returns (uint256) {
return a + b;
}
}
ご覧のとおり、このadd
関数は独立した電卓のようなものです。a
とb
を与えると、その合計を返します。コントラクトにどのようなデータが保存されているかには全く関心がありません。
まとめ:一枚の表で理解する
特性 | view 関数 | pure 関数 |
---|---|---|
コントラクトの状態変数を読み取る | ✅ 可能 | ❌ 不可能 |
コントラクトの状態変数を変更する | ❌ 不可能 | ❌ 不可能 |
入力パラメータに依存して計算する | ✅ 可能 | ✅ 可能 |
比喩 | 図書館の司書のように、資料を閲覧するだけ | 電卓のように、与えられた数値のみを処理する |
重要なポイント:なぜこれらを区別するのか?
view
とpure
を区別するのは、コードをより明確にするためだけではありません。より重要なのは、Gasを節約するためです!
-
外部からの呼び出しは無料:コントラクトの外部から(例:web3.jsを通じてウェブサイトのフロントエンドから)
view
またはpure
関数を呼び出す場合、この操作は完全に無料であり、Gasを消費しません。これは単にデータを読み取るだけで、ブロックチェーン上に新しいトランザクションを作成しないためです。これは、ユーザーにオンチェーンデータを表示する際に非常に役立ちます。 -
内部からの呼び出しはGasを節約:コントラクト関数Aが別の
view
またはpure
関数Bを呼び出す場合、Gasは消費されますが、状態を変更する関数を呼び出すよりもはるかに安価です。これは、高価なストレージ書き込み操作を実行しないためです。
したがって、有能なスマートコントラクト開発者として、view
とpure
を正しく使用する習慣を身につけることは非常に重要です。関数が論理的に状態の変更や読み取りを必要としない場合は、必ずpure
またはview
としてマークしてください。これにより、コードの安全性と意図がより明確になり、ユーザーの貴重なGas代を節約することもできます。