블록체인 학습
0 XP

require vs revert vs assert 가스 비교

세 가지 에러 도구는 "조건이 틀리면 되돌린다"는 점에서 비슷해 보이지만, 되돌림 타입과 가스 사용이 다릅니다. 올바른 도구를 골라야 가스를 아끼고 코드의 의도도 분명해집니다.

세 도구의 차이

도구용도되돌림 타입남은 가스
require입력·조건 검증Error(string) 또는 무메시지환불됨
revert흐름 제어형 되돌리기Error(string) 또는 커스텀 에러환불됨
assert내부 불변식 검사Panic(uint256)환불됨(0.8 이후)

require 와 revert 는 사용자가 마주칠 수 있는 정상적인 실패(잔액 부족, 권한 없음)를 표현하고, assert 는 절대 일어나면 안 되는 버그성 상황을 Panic 으로 표시합니다. 셋 다 0.8 이후로는 실패 시 남은 gas 를 환불합니다.

커스텀 에러가 가스를 아끼는 이유

가장 큰 가스 차이는 메시지 표현 방식에서 나옵니다. 긴 문자열 메시지(Error(string))는 바이트코드에 저장되어 배포·실행 비용을 높입니다. 같은 의미를 4바이트 선택자로 표현하는 커스텀 에러가 더 저렴합니다.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
 
error NotOwner();
 
contract Cheap {
    address public owner = msg.sender;
 
    // 비싼 방식: 긴 문자열이 바이트코드에 저장됨 (Error(string))
    function expensive() public view {
        require(msg.sender == owner, "caller is not the contract owner");
    }
 
    // 저렴한 방식: 4바이트 선택자만 인코딩됨 (커스텀 에러)
    function cheap() public view {
        if (msg.sender != owner) revert NotOwner();
    }
}

도구 선택 기준

  • 입력값/권한 검사처럼 흔하고 단순한 검증 → require (또는 if + revert 커스텀에러)
  • 복잡한 분기 끝에서 되돌릴 때, 가스를 아끼고 싶을 때 → revert 커스텀에러
  • "이건 절대 안 일어나야 한다"는 내부 가정 → assert

assert 는 절대 발생하면 안 되는 상황을 표시합니다. 정상 코드라면 assert 는 결코 실패하지 않아야 하므로, 사용자 입력 검증에는 쓰지 마세요. assert 가 실제로 깨졌다면 컨트랙트의 버그 신호입니다.

반복 호출되는 함수일수록 커스텀 에러의 가스 절감 효과가 누적됩니다. 검증이 많은 컨트랙트라면 커스텀 에러로 통일하세요.

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

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