Solidity의 함수 가시성(function visibility)이란?
Solidity 스마트 컨트랙트 프로그래밍에는 개발자가 지정된 제한에 따라 누가 또는 어떤 다른 스마트 컨트랙트가 자신의 함수를 호출할 수 있는지 결정할 수 있게 해주는 규정이 있습니다. 스마트 컨트랙트 함수와 상호작용할 수 있는 방식을 정의하는 이 기능을 **함수 가시성(function visibility)**이라고 합니다.
함수 가시성이란 무엇인가?
Solidity 스마트 컨트랙트의 함수 가시성 기능은 함수가 지정될 때 public, external, internal, private을 포함한 접근성 수준이 개발자가 의도한 대로 유지되도록 보장하는 데 사용됩니다.
개발자가 올바른 함수 가시성 타입을 사용하지 않거나 코드에 가시성 모델을 지정하지 않으면, 컨트랙트의 기본 public 가시성이 악용 가능한 보안 취약점에 노출됩니다. 함수 가시성을 지정하지 않았을 때의 보안상 영향 외에도, 함수가 적절한 지침 없이 작동하게 되므로 스마트 컨트랙트가 의도한 대로 작동하지 않을 수 있습니다.
누가 스마트 컨트랙트 함수를 호출할 수 있는가?
함수를 호출할 수 있는 컨트랙트에는 세 종류가 있습니다: 메인 컨트랙트 자체, 메인 컨트랙트로부터 상속받은 컨트랙트(DerivedContract), 그리고 제3자 컨트랙트(OutsideContract)입니다.
스마트 컨트랙트 호출하기란 스마트 컨트랙트에 포함된 내부 코드와 그 안에 담긴 데이터에 접근하는 것을 의미합니다. 이는 컨트랙트로부터 데이터를 가져오는 방법입니다.
1. 메인 컨트랙트 (MainContract)
이는 MainContract가 자신의 함수를 호출하는 구문입니다:
2. 메인 컨트랙트로부터 상속받은 컨트랙트 (DerivedContract)
이는 MainContract로부터 파생된 함수를 사용하는 DerivedContract의 구문입니다:
3. 제3자 컨트랙트 (OutsideContract)
이는 외부 함수에서 메인 컨트랙트를 호출하는 OutsideContract의 구문입니다.
함수 가시성 수정자와 상속은 어떻게 함께 작동하는가?
상속이란 "is" 키워드를 사용하여 한 컨트랙트의 내용이 다른 컨트랙트("파생 컨트랙트")에 복사되는 것을 말하며, 함수 수정자 가시성은 컨트랙트에 할당된 가시성 유형에 따라 파생된 자식 컨트랙트와 함께 작동합니다.
함수 가시성 수정자와 상속 간의 관계는 아래와 같이 설명됩니다:
- ParentContract 함수의 수정자가 public이면, _ChildContract_가 이를 접근할 수 있습니다.
- ParentContract 함수의 수정자가 internal이면, _ChildContract_가 이를 접근할 수 있습니다.
- ParentContract 함수의 수정자가 private이면, 상속받는 _ChildContract_는 이를 접근할 수 없습니다.
- ParentContract 함수의 수정자가 external이면, 상속받는 _ChildContract_는 이를 접근할 수 없습니다.
함수 가시성 수정자는 가스 최적화에 어떻게 도움이 되는가?
external 함수 가시성 수정자의 매개변수는 메모리에 저장되지 않고 calldata로부터 직접 읽히기 때문에, 스마트 컨트랙트는 가스를 덜 소비합니다. 반면 public 함수는 입력 매개변수가 메모리에 저장되므로 스마트 컨트랙트를 배포하는 데 더 많은 가스가 소요됩니다.
함수 가시성 수정자란 무엇인가?
함수 가시성 수정자에는 접근성이 가장 높은 것부터 가장 낮은 것까지 네 가지 유형이 있습니다: public, external, internal, private. 개발자는 누가 함수를 보고 호출할 수 있기를 원하는지에 따라 올바른 가시성으로 함수를 수정해야 합니다.
1. Public
public 함수는 세 가지 유형의 호출 컨트랙트인 메인 컨트랙트, 파생 컨트랙트, 제3자 컨트랙트 모두가 접근할 수 있습니다. 함수는 기본적으로 public입니다.
위 코드 예제에서 볼 수 있듯이, "public" 가시성 때문에 코드베이스 내 어떤 컨트랙트든 "functionPublic" 함수에 접근할 수 있습니다.
2. External
external 함수는 제3자만 호출할 수 있는 함수입니다. external 함수 가시성을 사용하면, 함수를 호출할 수 있는 컨트랙트는 메인 컨트랙트와 독립적이어야 하며 파생 컨트랙트일 수 없습니다.
위는 어떤 작업을 수행하는 임의의 컨트랙트(RandomContract)입니다. 아래 코드 스니펫은 RandomContract의 external 함수를 호출하는 external 컨트랙트입니다.
3. Internal
internal 함수는 메인 컨트랙트와 그로부터 파생된 모든 컨트랙트가 호출할 수 있습니다. internal 함수는 처음 선언된 메인 컨트랙트에서, 그리고 상속을 통해 이 메인 컨트랙트를 확장하는 컨트랙트들에서 접근할 수 있습니다.
4. Private
private 함수는 함수가 지정된 메인 컨트랙트에서만 호출할 수 있습니다. 일반적인 관례에 따라 처음에는 private 함수를 사용하지만, 범위가 이 수정자 유형보다 넓어지면 다른 적절한 수정자를 사용해야 합니다.
Solidity의 기본 함수 가시성은 무엇인가?
코드에서 함수의 가시성 수정자가 명시적으로 선언되지 않으면, 함수는 기본적으로 public 가시성으로 설정됩니다. 함수 가시성을 비워두고 Solidity 컴파일러가 기본 가시성을 사용하도록 두는 것은 권장되는 모범 사례가 아닙니다. 함수 가시성을 의도적으로 설정하면 코드 리뷰 시 코드를 더 읽기 쉽고 이해하기 쉽게 만듭니다.
함수 가시성 수정자와 상태 변수 가시성 수정자의 차이점은 무엇인가?
함수 가시성 수정자와 상태 변수 가시성 수정자의 차이점은 상태 변수에는 external 가시성 수정자 옵션이 없다는 것입니다.
상태 변수는 함수 호출 사이에 데이터를 지속적으로 보관하는 컨트랙트 저장소에 값이 영구적으로 저장되는 변수입니다. 함수 가시성 수정자와 마찬가지로, 상태 변수에도 Public, Private, Internal이라는 가시성 수정자가 있습니다.
상태 변수 가시성 수정자
상태 변수는 프로그램의 컨트랙트 섹션에서 선언됩니다. 변수의 데이터 타입이 지정된 후, 가시성 수정자가 변수에 할당됩니다.
1. Public
public 수정자를 가진 상태 변수는 애플리케이션 내 어떤 컨트랙트든 접근할 수 있습니다. 변수가 _public_으로 선언되면, 그 안에 저장된 데이터는 메인 컨트랙트, 파생 컨트랙트, 또는 외부 컨트랙트가 읽을 수 있습니다.
2. Internal
internal 수정자로 선언된 상태 변수는 정의된 컨트랙트 내에서와 파생 컨트랙트에서만 접근할 수 있습니다. 제3자나 다른 외부 컨트랙트는 internal 변수로 정의된 데이터의 저장소에 접근할 수 없습니다.
3. Private
상태 변수가 _private_이면, 선언된 메인 컨트랙트만 이를 호출할 수 있습니다. private 가시성 수정자는 메인 컨트랙트 이외의 다른 당사자의 접근을 제한하여 그 안에 담긴 데이터를 보호합니다.
Solidity의 기본 변수 가시성은 무엇인가?
변수 가시성이 정의되지 않으면 기본값은 internal입니다. 범위가 넓어지기 전까지는 변수를 private으로 선언하는 것이 모범 사례입니다.
Solidity에 대해 계속 학습하기
이 글에서는 Solidity 함수 가시성을 소개하고, 다음 프로젝트에 활용할 수 있는 설명과 자료를 제공합니다.
Solidity 언어를 처음 접하고 첫 스마트 컨트랙트를 만들고자 한다면, Alchemy University의 무료 온라인 Solidity 프로그래밍 강좌에서 자리를 확보하세요.
관련 개요

블록체인 매직을 만드세요
Alchemy는 가장 강력한 Web3 개발자 제품 및 도구를 리소스, 커뮤니티, 그리고 전설적인 지원과 결합합니다.


