Solidity Reference
Solidity 문법, 타입, 함수, 이벤트 빠른 참조
Solidity Reference 소개
Solidity 레퍼런스는 이더리움 스마트 컨트랙트 개발을 위한 검색 가능한 빠른 참조입니다. uint, int, address, address payable 등 기본 타입부터 mapping, struct, enum 같은 복합 데이터 구조까지 다룹니다. 각 항목에는 ERC-20 토큰, DeFi 프로토콜, NFT 컨트랙트에서 흔히 사용되는 실전 코드 예제가 포함되어 있습니다.
이 레퍼런스는 Solidity 구문을 타입, 함수, 이벤트, 상속, 저장소의 5가지 핵심 카테고리로 구성합니다. 함수 섹션에서는 가시성 수정자(public, private, internal, external), 언더스코어 플레이스홀더 패턴을 사용한 커스텀 modifier, ETH 수신을 위한 payable 함수, require/revert/assert를 활용한 오류 처리를 다룹니다. 이벤트 섹션에서는 오프체인 로그 필터링을 위한 indexed 파라미터 활용법을 설명합니다.
Solidity 고유 개념인 상속과 저장소 섹션도 포함합니다. IERC20 같은 인터페이스 정의, "using for" 구문을 활용한 라이브러리 사용법, 그리고 가스 비용에 직접 영향을 미치는 storage, memory, calldata 간의 핵심적인 차이를 확인할 수 있습니다. 모든 콘텐츠는 서버 호출 없이 브라우저에서 바로 실행됩니다.
주요 기능
- uint/int 크기, address vs address payable, bool, bytes, string을 포함한 완전한 타입 레퍼런스
- 실제 ERC-20 allowance 예제가 포함된 매핑 및 중첩 매핑 구문
- 사용 가이드라인이 포함된 함수 가시성 수정자(public, private, internal, external)
- onlyOwner 패턴과 언더스코어(_) 플레이스홀더를 활용한 커스텀 modifier 패턴
- 효율적인 로그 필터링을 위한 indexed 파라미터가 포함된 이벤트 정의
- 커스텀 에러 메시지를 포함한 require, revert, assert 오류 처리
- 인터페이스 및 라이브러리를 활용한 다중 컨트랙트 상속 패턴
- 가스 비용 영향이 설명된 storage vs memory vs calldata 데이터 위치 지정자
자주 묻는 질문
Solidity에서 address와 address payable의 차이점은 무엇인가요?
address는 20바이트 이더리움 주소를 보유하며 잔액 조회가 가능합니다. address payable은 추가로 transfer()와 send() 메서드를 지원하여 ETH 전송이 가능합니다. address에서 address payable로의 암시적 변환은 불가능하며 명시적 캐스팅이 필요합니다. 컨트랙트가 해당 주소로 ETH를 전송해야 할 때 address payable을 사용합니다.
require, revert, assert는 어떻게 다른가요?
require()는 입력 검증과 사전 조건에 사용되며, 실패 시 남은 가스를 환불합니다. revert()는 require와 유사하지만 if-else 블록 내에서 유용하며 커스텀 에러를 지원합니다. assert()는 내부 불변 조건 검사용으로, 실패 시 모든 남은 가스를 소비하여 컨트랙트 버그를 나타냅니다. 프로덕션 코드에서는 require()가 가장 많이 사용됩니다.
storage, memory, calldata는 언제 사용해야 하나요?
storage는 온체인에 영속적으로 저장되며 가장 비쌉니다. memory는 함수 실행 중에만 존재하는 임시 데이터입니다. calldata는 읽기 전용이며 external 함수 파라미터에 사용되고, 복사가 없어 memory보다 저렴합니다. external 함수 입력에는 calldata를, 로컬 변수에는 memory를, 상태 변수에만 storage를 사용하세요.
Solidity 이벤트에서 indexed 키워드는 무엇을 하나요?
indexed 키워드는 이벤트 파라미터에 대해 오프체인에서 해당 값으로 로그를 필터링할 수 있게 합니다. 각 이벤트당 최대 3개의 indexed 파라미터를 가질 수 있습니다. indexed 파라미터는 트랜잭션 로그에서 데이터가 아닌 토픽으로 저장되어 검색이 가능하지만 각각 32바이트로 제한됩니다.
Solidity에서 다중 상속은 어떻게 처리되나요?
Solidity는 C3 선형화를 사용하여 다중 상속을 해결합니다. 컨트랙트는 "is" 키워드 뒤에 가장 기본에서 가장 파생 순서로 나열됩니다. 여러 부모에 동일한 이름의 함수가 있으면 가장 파생된 버전이 사용됩니다. super 키워드는 직접 부모가 아닌 선형화된 계층 구조의 다음 컨트랙트를 호출합니다.
modifier에서 언더스코어(_) 패턴의 목적은 무엇인가요?
modifier의 언더스코어(_)는 수정된 함수의 본문이 삽입되는 위치를 나타냅니다. 언더스코어 앞의 코드는 사전 조건으로 실행되고(예: require(msg.sender == owner)), 뒤의 코드는 사후 조건으로 실행됩니다. 이 패턴을 통해 접근 제어 검사, 재진입 가드, 상태 검증을 여러 함수에서 재사용할 수 있습니다.
receive()와 fallback() 함수는 어떻게 작동하나요?
receive()는 컨트랙트가 calldata 없이 순수 ETH를 받을 때(예: transfer나 send를 통해) 호출됩니다. fallback()은 호출 서명과 일치하는 함수가 없거나 calldata와 함께 ETH가 전송될 때 호출됩니다. 둘 다 external이어야 합니다. 순수 ETH 전송을 받으려면 최소한 receive()가 필요하며, 없으면 직접 전송이 revert됩니다.
Solidity 라이브러리에서 "using A for B" 구문은 무엇인가요?
"using SafeMath for uint256"은 라이브러리의 모든 함수를 uint256 타입에 부착하여, SafeMath.add(value, 5) 대신 value.add(5)로 호출할 수 있게 합니다. 라이브러리 함수는 첫 번째 파라미터로 해당 타입을 가져야 합니다. 이 패턴은 안전한 산술 연산, 배열 유틸리티, 커스텀 타입 확장에 널리 사용됩니다.