Solidity 솔리디티 강좌 27강 : 에러 핸들러 - try/catch (1)

flowing1ife·2023년 7월 7일
0

[ Solidity 깨부수기 ]

목록 보기
27/29
post-thumbnail

Solidity 솔리디티 강좌 27강 : 에러 핸들러 - try/catch (1)
이번엔 solidity의 에러 핸들러, try/catch에 대해 알아보도록 하자.


try / catch

📌 Solidity

우리가 여태까지 본 기존의 에러핸들러는 에러를 발생시키고 프로그램을 끝냈다. 그러나 try/catch의 경우 에러가 났어도 프로그램을 종료시키지 않고 어떠한 대처를 하게 만들 수 있다.

try/catch 문 안에서 에러가 난다면 catch는 에러를 잡지 못하고 개발자가 의도했다고 생각하여 정상적으로 프로그램을 끝낸다.

catch Error (string memory reason) {} : revert나 require로 생성된 에러용도
catch Panic (uint errorCode){} : assert를 통해 생성된 에러가 날 때 잡힘
catch(bytesmemoryLowLevelData){} : low level 에러를 잡음

try/catch 문은 다음과 같은 상황에서 사용된다.

  1. 외부 스마트 컨트랙 함수를 부를 때 : 다른 스마트 컨트랙트를 인스턴스화 하여서 try/catch 문이 있는 스마트 컨트랙트의 함수를 불러와서 사용
  2. 외부 스마트 컨트랙을 생성할 때 : 다른 스마트 컨트랙트를 인스턴스화 생성할 때 사용
  3. 스마트 컨트랙트 내에서 함수를 부를 때 : 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);
        }

다음과 같이 코드를 작성하였다. 결과를 보며 함께 분석해보자.

1. catchErr

👉 결과

catchErrrevert, require 로 생성된 에러를 catch 하므로 _num1 의 값을 10 이상으로 설정한다면 다음과 같이 require 에러를 출력하며 (0,false)를 return 한다.

2. catchPanic

👉 결과

catchPanicassert로 생성된 에러를 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 한다.


출처 및 참고 자료

profile
👩🏻‍💻 Backend Engineer, Contract Developer

0개의 댓글