Solidityにおける`view`関数と`pure`関数の違いは何ですか?

Carlos Howard
Carlos Howard
Blockchain architect with 8 years' Ethereum experience; 8年以太坊开发经验的区块链架构师。

はい、もちろんです。Solidityにおけるviewpureについてお話しましょう。この二つは、実はとても区別しやすいものです。

viewpureの違い:一つは見るだけ、もう一つは見ることもない

レストランに入った状況を想像してみてください。

  • 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関数は独立した電卓のようなものです。abを与えると、その合計を返します。コントラクトにどのようなデータが保存されているかには全く関心がありません。


まとめ:一枚の表で理解する

特性view関数pure関数
コントラクトの状態変数を読み取る✅ 可能不可能
コントラクトの状態変数を変更する❌ 不可能❌ 不可能
入力パラメータに依存して計算する✅ 可能✅ 可能
比喩図書館の司書のように、資料を閲覧するだけ電卓のように、与えられた数値のみを処理する

重要なポイント:なぜこれらを区別するのか?

viewpureを区別するのは、コードをより明確にするためだけではありません。より重要なのは、Gasを節約するためです!

  1. 外部からの呼び出しは無料:コントラクトの外部から(例:web3.jsを通じてウェブサイトのフロントエンドから)viewまたはpure関数を呼び出す場合、この操作は完全に無料であり、Gasを消費しません。これは単にデータを読み取るだけで、ブロックチェーン上に新しいトランザクションを作成しないためです。これは、ユーザーにオンチェーンデータを表示する際に非常に役立ちます。

  2. 内部からの呼び出しはGasを節約:コントラクト関数Aが別のviewまたはpure関数Bを呼び出す場合、Gasは消費されますが、状態を変更する関数を呼び出すよりもはるかに安価です。これは、高価なストレージ書き込み操作を実行しないためです。

したがって、有能なスマートコントラクト開発者として、viewpureを正しく使用する習慣を身につけることは非常に重要です。関数が論理的に状態の変更や読み取りを必要としない場合は、必ずpureまたはviewとしてマークしてください。これにより、コードの安全性と意図がより明確になり、ユーザーの貴重なGas代を節約することもできます。