visibility 전체 복습
접근 제어를 본격적으로 배우기 전에, 앞서 익힌 가시성(visibility) 키워드 네 가지를 정리합니다.
가시성은 "누가 이 함수나 변수에 접근할 수 있는가"를 결정하는 첫 번째 방어선입니다.
Solidity 에서 함수의 가시성은 반드시 명시해야 하며, 생략하면 컴파일 오류가 납니다.
public, external, internal, private
| 키워드 | 외부 호출 | 같은 컨트랙트 내부 | 상속한 자식 |
|---|---|---|---|
public | 가능 | 가능 | 가능 |
external | 가능 | 직접 호출 불가 | 직접 호출 불가 |
internal | 불가 | 가능 | 가능 |
private | 불가 | 가능 | 불가 |
public 은 가장 열린 단계로, 상태 변수에 붙이면 동일한 이름의 자동 getter 함수가 만들어집니다.
반대로 private 는 가장 닫힌 단계로, 선언한 컨트랙트 안에서만 접근할 수 있습니다.
외부에서만 부르는 API 함수에는 external 을 씁니다. 인자를 콜데이터에서 곧바로 읽기 때문에
public 보다 가스가 조금 덜 듭니다.
private 라고 해서 데이터가 비밀이 되는 것은 아닙니다. 블록체인의 모든 데이터는 공개되어 있어
누구나 읽을 수 있습니다. private 는 단지 다른 컨트랙트가 코드로 접근하지 못하게 막을 뿐입니다.
가시성을 적용한 컨트랙트
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract VisibilityDemo {
uint256 public publicVar = 1; // 자동 getter 생성
uint256 internal internalVar = 2; // 자식 컨트랙트까지 접근
uint256 private privateVar = 3; // 이 컨트랙트에서만 접근
function externalFn() external pure returns (uint256) {
return 10;
}
function internalFn() internal pure returns (uint256) {
return 20;
}
}최소 권한 원칙
좋은 컨트랙트는 가장 좁은 가시성부터 시작합니다. 외부에 꼭 노출해야 하는 함수만 public/external
로 열고, 나머지는 internal/private 로 닫아야 안전합니다.
가시성을 넓게 열어두면 의도치 않은 외부 호출이 자금 탈취나 상태 변조의 통로가 될 수 있습니다.
의심스러울 때는 일단 private 또는 internal 로 좁게 선언하고, 외부 접근이 정말 필요할 때만
넓혀가세요. "기본은 닫기"가 보안의 출발점입니다.
가시성은 접근 자체를 막는 정적인 제어입니다. 조건에 따라 접근을 허용하는 modifier 나 require
와는 성격이 다릅니다.