블록체인 학습
0 XP

assert 문

assert 는 절대 일어나서는 안 되는 조건, 곧 불변식(invariant)을 검사하는 도구입니다. 정상적인 코드라면 결코 거짓이 될 수 없는 조건을 확인하는 "내부 버그 탐지기"인 셈입니다.

require vs revert vs assert

구문용도실패 시 에러 타입남은 가스
require사용자 입력·권한 검증Error(string)환불
revert복잡한 조건 분기에서 명시적 중단Error 또는 커스텀환불
assert내부 불변식·버그 검사Panic(uint256)환불

핵심 차이는 에러 타입입니다. require/revert 는 Error 를, assert 는 Panic 을 던집니다. 0.8.0 부터는 셋 다 실패하면 남은 가스를 호출자에게 환불합니다. 0.8.0 이전에는 assert 만 남은 가스를 전부 소모했지만, 이제는 그 차이가 사라졌습니다.

불변식 검사 예시

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
 
contract Ledger {
    uint256 public total;
    mapping(address => uint256) public balance;
 
    function deposit() public payable {
        uint256 totalBefore = total;
 
        balance[msg.sender] += msg.value;
        total += msg.value;
 
        // 불변식 1: total 은 정확히 입금액만큼만 늘어나야 한다
        assert(total == totalBefore + msg.value);
        // 불변식 2: 장부에 기록된 총합이 실제 보유 잔액을 넘을 수 없다
        assert(total <= address(this).balance);
    }
}

언제 무엇을 쓰는가

판단 기준은 간단합니다. 외부에서 들어온 값(사용자 입력, 권한)을 검사하면 require, 코드가 스스로 보장해야 할 내부 상태를 검사하면 assert 입니다. 0.8.0 이상에서는 정수 오버플로/언더플로나 0으로 나누기 같은 상황도 자동으로 Panic 을 발생시켜 assert 와 같은 계열로 보호해 줍니다.

실무에서 assert 는 자주 쓰이지 않습니다. 대부분의 검사는 require 로 충분하며, assert 는 핵심 회계 불변식처럼 "절대 깨지면 안 되는" 마지막 안전망에만 아껴 사용합니다.

assert 가 실패한다는 것은 곧 컨트랙트 로직에 결함이 있다는 신호입니다. "여기까지 오면 코드에 버그가 있다"는 상황에만 쓰세요.

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

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