導入
処理のまとまりが 関数(function) です。Solidity の関数には「台帳を書き換えるか / 読むだけか」で種類があり、これがガス(手数料)の有無に直結します。
説明
先ほどの count を増やしたり読んだりする関数を足してみます。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract Counter {
uint256 public count = 0;
// 状態を書き換える関数(トランザクション:ガスがかかる)
function increment() public {
count = count + 1;
}
// 状態を読むだけの関数(view:外部からの呼び出しは無料)
function getCount() public view returns (uint256) {
return count;
}
// 引数だけで計算し状態に触れない関数(pure)
function add(uint256 a, uint256 b) public pure returns (uint256) {
return a + b;
}
}
function increment() public { ... }…countを書き換える。状態を変える処理はトランザクションとして記録され、ガスがかかる。view… 状態を読むだけで変更しないと約束する関数。外部から単に読むだけなら無料。pure… 状態を読みも書きもせず、引数だけで計算する関数。これも読み取りは無料。returns (uint256)… 戻り値の型。複数返すこともできる。
graph TD
F[関数] --> W["状態を変更する<br/>(書き込み)"]
F --> R["状態を変更しない<br/>(読み取り)"]
W --> TX["トランザクション<br/>ガスが必要・台帳更新"]
R --> VP["view / pure<br/>外部呼び出しは無料"]
「お金(ガス)がかかるのは、台帳を書き換えるときだけ」――この原則を押さえると、view / pure を付ける意味が見えてきます。
やってみよう
getCount から view を外すと、コンパイラが「状態を変えていないなら view を付けなさい」と警告します。逆に view を付けた関数の中で count = ... と書き換えようとするとエラーになります。宣言した約束は言語が守らせてくれるわけです。