Solidityのアクセス修飾子について解説します。
アクセス修飾子には「public/private/internal/external」の4種類があります。
public
public修飾子を付けた場合は、外部から直接アクセスが可能になります。
また、コントラクト内部や継承先コントラクトからも呼び出しが可能です。
関数の呼び出しでは、引数の値がいったんメモリに保存されるため、実行コスト(ガス代)はexternal修飾子に比べ高くなります。
データ型 public 変数名;
function 関数名(データ型 引数) public [関数修飾子] [returns(データ型)] {
}
private
private修飾子を付けた場合は、同じスマートコントラクト内からのみアクセスが可能になります。
また、継承先コントラクトからの呼び出しは不可です。
データ型 private 変数名;
function 関数名(データ型 引数) private [関数修飾子] [returns(データ型)] {
}
internal
internal修飾子を付けた場合は、同じスマートコントラクト内からのみアクセスが可能になります。
ただ、private修飾子とは異なり、継承先コントラクトからの呼び出しは可能です。
データ型 internal 変数名;
function 関数名(データ型 引数) internal [関数修飾子] [returns(データ型)] {
}
external
external修飾子を付けた場合は、外部スマートコントラクトからのみ呼び出しが可能になります。
また、public修飾子とは異なり、コントラクト内部や継承先コントラクトからの呼び出しも不可です。
関数の呼び出しにおいて、引数の値はメモリに保存されないため、実行コスト(ガス代)はpublic修飾子に比べ安くなります。
function 関数名(データ型 引数) external [関数修飾子] [returns(データ型)] {
}
アクセス修飾子の比較まとめ
各アクセス修飾子の比較をまとめた表は以下となります。
コントラクト内部 | 外部コントラクト | 継承先コントラクト | 対象(変数/関数) | 備考 | |
---|---|---|---|---|---|
public | ○ | ○ | ○ | 両方 | externalに比べコスト(ガス代)が高い |
private | ○ | × | × | 両方 | - |
internal | ○ | × | ○ | 両方 | - |
external | × | ○ | × | 関数のみ | publicに比べコスト(ガス代)が低い |
サンプルコード
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract Test {
/* 変数 */
// Public
uint256 public publicVariable = 10;
// Private
uint256 private privateVariable = 10;
// Internal
uint256 internal internalVariable = 10;
/* 関数 */
// Public
function publicFunction(uint num) public pure returns(uint) {
return num;
}
// Private
function privateFunction(uint num) private pure returns(uint) {
return num;
}
// Internal
function internalFunction(uint num) internal pure returns(uint) {
return num;
}
// External
function externalFunction(uint num) external pure returns(uint) {
return num;
}
}
スマートコントラクトを書く上で最も気を付けないといけないのがセキュリティです。一歩間違うと、スマコン上に貯まっている資金が全て奪われてしまう事態になりかねません。そのためにも、各アクセス修飾子の特性について、確実にマスターしておきましょう。