Solidity 솔리디티 강좌 27강 : 에러 핸들러 - try/catch (1)
이번엔 solidity의 에러 핸들러, try/catch에 대해 알아보도록 하자.
우리가 여태까지 본 기존의 에러핸들러는 에러를 발생시키고 프로그램을 끝냈다. 그러나 try/catch의 경우 에러가 났어도 프로그램을 종료시키지 않고 어떠한 대처를 하게 만들 수 있다.
try/catch 문 안에서 에러가 난다면 catch는 에러를 잡지 못하고 개발자가 의도했다고 생각하여 정상적으로 프로그램을 끝낸다.
catch Error (string memory reason) {} : revert나 require로 생성된 에러용도
catch Panic (uint errorCode){} : assert를 통해 생성된 에러가 날 때 잡힘
catch(bytesmemoryLowLevelData){} : low level 에러를 잡음
try/catch 문은 다음과 같은 상황에서 사용된다.
- 외부 스마트 컨트랙 함수를 부를 때 : 다른 스마트 컨트랙트를 인스턴스화 하여서 try/catch 문이 있는 스마트 컨트랙트의 함수를 불러와서 사용
- 외부 스마트 컨트랙을 생성할 때 : 다른 스마트 컨트랙트를 인스턴스화 생성할 때 사용
- 스마트 컨트랙트 내에서 함수를 부를 때 : this를 통해 try/catch 사용
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract math{
function division(uint256 _num1,uint256 _num2) public pure returns (uint256){
require(_num1<10,"num1 shoud not be more than 10");//
return _num1/_num2; //6/3 => 2
}
}
contract runner{
event catchErr(string _name,string _err);
event catchPanic(string _name,uint256 _err);
event catchLowLevelErr(string _name,bytes _err);
math public mathInstance = new math() ;
function playTryCatch(uint256 _num1, uint256 _num2) public returns(uint256,bool){
try mathInstance.division(_num1, _num2) returns(uint256 value){
return(value,true);
} catch Error(string memory _err) {
emit catchErr("revert/require",_err);
return(0,false);
} catch Panic(uint256 _errorCode) {
emit catchPanic("assertError/Panic",_errorCode);
return(0,false);
} catch (bytes memory _errorCode) {
emit catchLowLevelErr("LowlevelError",_errorCode);
return(0,false);
}
다음과 같이 코드를 작성하였다. 결과를 보며 함께 분석해보자.
👉 결과
catchErr
는 revert, require
로 생성된 에러를 catch 하므로 _num1
의 값을 10 이상으로 설정한다면 다음과 같이 require
에러를 출력하며 (0,false)
를 return 한다.
👉 결과
catchPanic
은 assert
로 생성된 에러를 catch한다.
solidity에서 정의한 Panic 타입의 에러는 다음과 같이 10가지가 있다.
0x00: Used for generic compiler inserted panics.
0x01: If you call assert with an argument that evaluates to false.
0x11: If an arithmetic operation results in underflow or overflow outside of an unchecked { ... } block.
0x12; If you divide or modulo by zero (e.g. 5 / 0 or 23 % 0).
0x21: If you convert a value that is too big or negative into an enum type.
0x22: If you access a storage byte array that is incorrectly encoded.
0x31: If you call .pop() on an empty array.
0x32: If you access an array, bytesN or an array slice at an out-of-bounds or negative index (i.e. x[i] where i >= x.length or i < 0).
0x41: If you allocate too much memory or create an array that is too large.
0x51: If you call a zero-initialized variable of internal function type.
이 중에서 우리는 0으로 나누면 발생하는 에러인 0x12 에러를 발생시켜보았다. 인자값을 0으로 넘기면 다음과 같이 assert
에러, 그 중에서도 0x12 ( 이를 십진수로 바꾸면 18 ) 에러를 출력하며 (0,false)
를 return 한다.
출처 및 참고 자료