블록체인 학습
0 XP

추상 컨트랙트 (abstract)

추상 컨트랙트(abstract contract) 는 인터페이스와 일반 컨트랙트의 중간에 있는 개념입니다. 일부 함수는 구현하고, 일부 함수는 구현하지 않은 채로 남겨둘 수 있습니다. 즉 "공통으로 쓸 코드는 미리 채워주고, 나머지 빈칸은 자식에게 맡기는" 반쯤 완성된 설계도입니다.

구현되지 않은 함수가 하나라도 있으면 그 컨트랙트는 반드시 abstract 로 선언해야 합니다. 추상 컨트랙트는 단독으로 배포할 수 없고, 상속받아 나머지를 완성한 컨트랙트만 배포할 수 있습니다.

인터페이스와 다른 점

인터페이스가 "껍데기 약속"만 담는다면, 추상 컨트랙트는 그보다 훨씬 자유롭습니다.

  • 함수 구현을 가질 수 있다. 일부만 비워두어도 된다.
  • 상태 변수를 둘 수 있다.
  • 생성자(constructor) 도 정의할 수 있다.
  • 함수 가시성은 public·internal 등 원하는 대로 쓴다.

미구현 함수에는 virtual 키워드를 붙여 "자식이 채워야 한다"는 것을 표시합니다.

virtual과 override의 짝

부모의 미구현(또는 재정의 가능) 함수에는 virtual, 자식이 채우는 함수에는 override 를 붙입니다. 이 둘이 짝을 이뤄 안전한 다형성 을 만듭니다.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
 
// 구현하지 않은 함수가 있으므로 abstract 로 선언한다.
abstract contract Animal {
    string public species;
 
    constructor(string memory _species) {
        species = _species;
    }
 
    // 구현 있음: 공통 동작
    function describe() public view returns (string memory) {
        return species;
    }
 
    // 구현 없음: 자식이 채워야 함 (virtual)
    function sound() public view virtual returns (string memory);
}
 
// 추상 컨트랙트를 상속해 나머지를 완성하면 배포할 수 있다.
contract Dog is Animal {
    constructor() Animal("Dog") {}
 
    function sound() public pure override returns (string memory) {
        return "Woof";
    }
}

여러 컨트랙트가 공통 상태와 공통 로직을 공유하면서 일부 동작만 다르게 해야 할 때 추상 컨트랙트가 최적입니다. OpenZeppelin 의 많은 기반 컨트랙트가 이 방식으로 설계되어 있습니다.

Code Editor
에디터를 불러오는 중...
실행 결과

Run 버튼을 눌러 코드를 실행하세요.