---
title: "Solidity 에러 처리"
description: "Require, Revert, Assert의 용도와 차이점 알아보기"
---

## Solidity에서 에러 처리는 어떻게 작동하는가?

[Solidity](https://www.alchemy.com/overviews/solidity)는 에러 처리를 위해 상태를 되돌리는 예외\(state-reverting exception\)를 사용하며, 이러한 예외는 현재 호출에서 상태에 가해진 모든 변경 사항을 취소하는 동시에 호출자에게 에러를 알린다.

Solidity는 Ethereum과 같은 블록체인에서 [스마트 컨트랙트](https://www.alchemy.com/overviews/solidity-smart-contract)를 구현하기 위한 객체 지향 프로그래밍 언어로, 컴파일 시점이나 런타임에 발생할 수 있는 근본적인 문제를 다루기 위한 다양한 함수를 갖추고 있다. 구문 오류 검사는 컴파일 시점에 이루어지지만, 런타임 에러는 잡아내기 어려우며 주로 컨트랙트 실행 과정에서 발생한다. 런타임 에러의 예로는 0으로 나누는 유형의 에러, 배열 인덱스 초과 에러 등이 있다.

결과적으로 Solidity의 에러 처리는 **원자성**\(atomicity\)이라는 속성을 보장한다. 스마트 컨트랙트 호출이 에러와 함께 종료되면, 모든 상태 변경\(즉, 변수, 잔액 등에 가해진 변경\)은 컨트랙트 호출 체인을 따라 위로 모두 되돌려진다.

여기서 중요한 점은 개발자가 [인터페이스를 선언](https://www.alchemy.com/overviews/solidity-interface)함으로써 다른 컨트랙트와 직접 상호작용할 수 있다는 것이다. Ethereum 블록체인에서 트랜잭션은 원자적이며, 이는 트랜잭션이 완전히 완료되거나 아니면 상태에 아무런 영향도 주지 않고 전부 되돌려진다는 것을 의미한다.

## Solidity의 세 가지 주요 에러 처리 함수는 무엇인가?

Solidity에서 에러 처리는 원칙적으로 세 가지 [**특수 함수**](https://www.alchemy.com/overviews/solidity-functions)인 assert, require, revert에 의해 관리된다. 버전 0.4.10까지는 Solidity에서 단일 throw 문만 사용할 수 있었다.

Solidity는 [Ethereum Virtual Machine](https://www.alchemy.com/overviews/what-is-the-ethereum-virtual-machine-evm)\(EVM\)을 대상으로 설계되었으며 C++, Javascript, Python의 영향을 받았다. Solidity를 사용하면 개발자는 투표, 크라우드펀딩, 다중 서명 지갑, 심지어 블라인드 경매와 같은 용도의 컨트랙트를 만들 수 있다.

실제로 이는 개발자가 근본적인 값을 확인하고 에러를 발생시키기 위해 여러 테스트 함수를 작성해야 했다는 것을 의미하며, 이는 [가스에 대해 최적화되지](https://www.alchemy.com/overviews/solidity-gas-optimization) 않은 방식이었다. Solidity 버전 0.4.10이 출시되면서 asset, require, revert라는 새로운 에러 처리 구문이 도입되었고 throw는 더 이상 사용되지 않게 되었다.

### require 함수란 무엇인가?

_require_ 함수는 실행 전에 입력값과 조건을 검증하는 데 사용된다. 예를 들어 조건이 false이면 require 함수는 즉시 실행을 중단한다. 다시 말해 require는 [게이트 체크 수정자](https://www.alchemy.com/overviews/solidity-modifier)로 작동하여, 로직이 함수의 추가 실행에 접근하는 것을 막고 그 결과 에러를 발생시킨다. require는 로직 흐름을 통제하고 함수에 대한 사용자 입력을 검증하는 데 적합하다.

require 문은 함수를 실행하기 위해 코드 실행 전에 충족되어야 하는 전제 조건을 선언한다. _require_ 함수는 단일 인자를 받으며, 평가 후 require는 true 또는 false의 불리언 값을 반환한다. false 조건으로 인해 실행이 종료되는 경우, 사용되지 않은 가스는 호출자에게 반환되고 상태는 원래 상태로 되돌려진다. 사용자 지정 문자열 메시지도 추가할 수 있다.

**다음은 Solidity의 require 문 예시이다:**

<ImageBlock
  src="https://media.alchemy.com/1703928524-how-to-use-the-require-statement.png"
  alt="기본 예제는 require 문 사용법을 보여줍니다"
  width={859}
  height={291}
  caption="기본 예제는 require 문 사용법을 보여줍니다"
/>

#### require 문 사용 사례

실용적인 이유로, 개발자는 다음과 같은 상황에서 _require_를 사용할 수 있다:

1. 외부 컨트랙트로부터의 응답 검증
1. 최종 실행 전 상태 조건 확인
1. 사용자 입력 인증

### revert 문이란 무엇인가?

revert는 어떤 조건도 평가하지 않으며 어떤 상태나 문에도 의존하지 않는다. revert 문은 require 함수와 동일한 유형의 에러를 처리할 수 있다는 점에서 require 문과 유사하지만, 더 복잡한 로직 게이트에 더 적합하다.

_revert_ 문이 호출되면, 사용되지 않은 가스는 반환되고 상태는 원래 상태로 되돌려진다. 사용자 지정 메시지를 추가할 수 있는 기능은 _require_ 함수와 동일하다.

다음은 Solidity의 revert 문 예시이다:

### assert 함수란 무엇인가?

assert는 절대 false가 되어서는 안 되는 코드를 확인하는 데 사용되는 함수로, 불가능한 시나리오를 방지하는 데 중요한 역할을 한다. assert 함수가 true의 불리언 값을 반환하면, 치명적인 버그가 표시되고 프로그램은 실행되지 않는다.

_require_ 및 _revert_ 함수와 달리, _assert_는 사용되지 않은 가스를 전혀 반환하지 않으며, 대신 _assert_ 함수는 프로그램을 원래 상태로 되돌리기 전에 가스 공급량을 모두 소비한다. 흥미롭게도, Byzantium 포크 이전에는 _require_와 _assert_ 함수가 동일하게 작동했지만, 서로 다른 옵코드로 컴파일되었다.

#### assert 유형 예외

1. 값이 0으로 나누어지거나 0에 대해 모듈로 연산이 수행되는 경우
1. 함수의 0으로 초기화된 변수가 호출되는 경우
1. 음수나 지나치게 큰 값이 enum으로 변환되는 경우
1. 음수이거나 예상보다 큰 인덱스로 배열에 접근하는 경우

_assert_ 문 예시:

#### assert 문 사용 사례

이론적으로 _assert_는 _require_ 함수에 비해 덜 자주 사용되어야 한다. 개발자는 다음과 같은 사용 사례에서 _assert_ 함수 사용을 고려해야 한다:

- 변경 사항 적용 후 컨트랙트 상태 검증
- 절대 발생해서는 안 되는 조건 방지
- 오버플로우와 언더플로우 매개변수 확인
- 불변식 검사

## require vs. revert vs. assert

다음은 Solidity의 세 가지 에러 처리 함수인 _require_, _revert_, _assert_에 대한 간결한 요약이다.

#### require

- 함수 시작 부분에서 사용됨
- 잘못된 입력값에 대해 검증
- 실행 전 상태 조건 확인
- 남은 가스 환불

#### revert

- require와 동일함
- 더 복잡한 로직 흐름 게이트\(즉, 복잡한 if-then 블록\)에 유용함
- 남은 가스 환불

#### assert

- 함수 끝부분에서 사용됨
- 불가능한 것을 검증
- 정적 코드 분석 도구에 있어 중요함
- 남은 가스를 환불하지 않음

## require와 Solidity 에러 처리에 대해 더 알아보는 방법

[Solidity 에러 처리에 대해 더 알아보고](https://www.alchemy.com/overviews/learn-solidity) 싶은 개발자는 Alchemy University의 [무료 Solidity 개발자 크래시 코스](https://university.alchemy.com/?a=382cc2e126)에 등록하면 된다. 이 무료 7주 부트캠프는 web2 개발자와 완전히 새로운 코더가 Solidity 스마트 컨트랙트를 작성하는 법을 배우는 데 도움을 준다. 개발이 처음인 개발자라면, Ethereum 부트캠프를 시작하기 전에 Alchemy University의 [**3주 JavaScript 크래시 코스**](https://www.alchemy.com/university/courses/js)를 먼저 수강하는 것이 좋다.
