---
title: "Solidityにおけるfunction visibilityとは？"
description: "Public、External、Internal、Privateのfunction visibilityの違いを学ぶ"
---

# Solidityにおけるfunction visibilityとは？

[Solidity](https://www.alchemy.com/overviews/solidity)によるスマートコントラクトのプログラミングでは、開発者が指定した制限に基づいて、誰が、あるいはどの他のスマートコントラクトが自分の関数を呼び出せるかを決定できる仕組みがある。[スマートコントラクトの関数](https://www.alchemy.com/overviews/solidity-functions)がどのようにやり取りされるかを定義するこの機能は、**function visibility**（関数の可視性）と呼ばれる。

## **function visibilityとは何か**

Solidityのスマートコントラクトにおけるfunction visibility機能は、関数が指定された際に、その到達可能性のレベル（public、external、internal、private）が開発者の意図通りに維持されることを保証するために使用される。

開発者が適切なfunction visibilityの型を使用しない場合、あるいはコード内でvisibilityモデルが一切指定されない場合、コントラクトはデフォルトのpublic visibilityとなり、悪用され得るセキュリティ上の脆弱性にさらされる。function visibilityを指定しないことによるセキュリティ上の影響に加えて、関数が適切な指示なしに動作することになるため、スマートコントラクトが意図通りに機能しない可能性もある。

### **誰がスマートコントラクトの関数を呼び出せるのか**

**関数を呼び出せるコントラクトには3種類ある。メインコントラクト自身、メインコントラクトから継承されたコントラクト（DerivedContract）、そしてサードパーティのコントラクト（OutsideContract）である。**

[スマートコントラクトを呼び出す](https://www.alchemy.com/overviews/solidity-call)とは、スマートコントラクト内に含まれる内部コードと、そこに含まれるデータにアクセスすることを意味する。これはコントラクトからデータを取得する方法である。

#### **1. メインコントラクト（MainContract）**

以下はMainContractが自身の関数を呼び出す際の構文である。

#### **2. メインコントラクトから継承されたコントラクト（DerivedContract）**

以下はDerivedContractがMainContractから継承した関数を使用する際の構文である。

#### **3. サードパーティのコントラクト（OutsideContract）**

以下はOutsideContractが外部の関数からメインコントラクトを呼び出す際の構文である。

## **function visibility修飾子と継承はどのように連動するのか**

**継承とは、あるコントラクトの内容が「is」キーワードを使って別のコントラクト（「derived contract」）にコピーされることであり、function修飾子のvisibilityは、コントラクトに割り当てられたvisibilityの種類に応じて、継承先の子コントラクトと連動して動作する。**

function visibility修飾子と継承の関係は以下の通りである。

- _ParentContract_の関数の修飾子が**public**の場合、_ChildContract_はそれにアクセスできる。
- _ParentContract_の関数の修飾子が**internal**の場合、_ChildContract_はそれにアクセスできる。
- _ParentContract_の関数の修飾子が**private**の場合、継承先の_ChildContract_はそれにアクセスできない。
- _ParentContract_の関数の修飾子が**external**の場合、継承先の_ChildContract_はそれにアクセスできない。

## **function visibility修飾子はガスの最適化にどう役立つのか**

external function visibility修飾子のパラメータはメモリに保存されず、calldataから直接読み取られるため、[スマートコントラクトが消費するガスは少なくなる](https://www.alchemy.com/overviews/solidity-gas-optimization)。一方、public関数では入力パラメータがメモリに保存されるため、スマートコントラクトのデプロイにより多くのガスがかかる。

## **function visibility修飾子とは何か**

function visibility修飾子には、最も到達可能なものから最も限定的なものまで、public、external、internal、privateの4種類がある。開発者は、誰にその関数を見せて呼び出させたいかに応じて、適切なvisibilityで[関数を修飾する](https://www.alchemy.com/overviews/solidity-modifier)べきである。

### **1. Public**

**public関数は、3種類の呼び出し元コントラクトのいずれからでもアクセスできる。すなわちメインコントラクト、derived contract、そしてサードパーティのコントラクトである。関数はデフォルトでpublicとなる。**

上記のコードサンプルに示した通り、「public」のvisibilityにより、コードベース内のどのコントラクトからも「`functionPublic`」関数にアクセスできる。

### **2. External**

**external関数とは、サードパーティのみが呼び出せる関数のことである。** external function visibilityでは、その関数を呼び出せるコントラクトはメインコントラクトから独立していなければならず、derived contractであってはならない。

上はあるタスクを実行しているランダムなコントラクト（`RandomContract`）である。以下のコードスニペットは、`RandomContract`上のexternal関数を呼び出しているexternalコントラクトである。

### **3. Internal**

**internal関数は、メインコントラクトおよびそのderived contractのいずれからも呼び出せる。** internal関数は、最初に宣言されたメインコントラクトから、また継承を通じてこのメインコントラクトを拡張したコントラクトからアクセス可能である。

### **4. Private**

**private関数は、それが指定されたメインコントラクトからのみ呼び出せる。** private関数は一般的な慣行として最初に使用されるが、スコープがこの修飾子の型よりも広い場合は、他の適切な修飾子を使用すべきである。

### **Solidityにおけるデフォルトのfunction visibilityとは何か**

コード内で関数のvisibility修飾子が明示的に宣言されていない場合、その関数はデフォルトでpublic visibilityに設定される。function visibilityを空欄のままにして、Solidityコンパイラのデフォルトvisibilityに頼ることは推奨されるベストプラクティスではない。function visibilityを意図的に設定することで、コードレビュー時にコードがより読みやすく、理解しやすくなる。

## **function visibility修飾子とstate variable visibility修飾子の違いは何か**

**function visibility修飾子とstate variable visibility修飾子の違いは、state variableにはexternal visibility修飾子の選択肢がないという点である。**

state variableとは、その値がコントラクトのストレージに永続的に保存される変数であり、関数呼び出しの間もデータを永続的に保持する。function visibility修飾子と同様に、state variableにもPublic、Private、Internalというvisibility修飾子がある。

### **state variable visibility修飾子**

state variableはプログラムのcontractセクションで宣言される。変数のデータ型が指定され、その後にvisibility修飾子が変数に割り当てられる。

#### **1. Public**

_public_修飾子を持つstate variableは、アプリケーション内のどのコントラクトからもアクセスできる。変数が_public_として宣言されている場合、そこに保存されているデータはメインコントラクト、derived contract、あるいはexternalコントラクトのいずれからも読み取ることができる。

#### **2. Internal**

_internal_修飾子で宣言されたstate variableは、それが定義されたコントラクト内、およびderived contractからのみアクセスできる。サードパーティや他のexternalコントラクトは、_internal_変数として定義されたデータのストレージにアクセスできない。

#### **3. Private**

state variableが_private_の場合、それが宣言されたメインコントラクトのみがそれを呼び出せる。_private_ visibility修飾子は、メインコントラクト以外の他者からのアクセスを制限し、それが保持するデータを保護する。

### **Solidityにおけるデフォルトの変数visibilityとは何か**

変数のvisibilityが定義されていない場合、デフォルト値はinternalとなる。スコープが広がるまでは変数をprivateとして宣言しておくのがベストプラクティスである。

## **Solidityについてさらに学ぶ**

この記事では、Solidityのfunction visibilityについて紹介し、次のプロジェクトで活用できる説明とリソースを提供した。

Solidity言語に不慣れで、初めてのスマートコントラクトを構築しようとしているなら、Alchemy Universityの無料の[オンラインSolidityプログラミングコース](https://alchemy.com/university/courses/solidity?a=d7f2788ae5)で自分の席を確保してほしい。
