2020.코딩일지
[solidity] error/try-catch문 (feat.솔리디티깨부수기) 본문
728x90
error
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
//에러핸들러: require, revert, assert, try/catch
/*
0.4.22 ~ 0.7.x
assert: gas를 다 소비한 후, 특정한 조건에 부합하지 않으면 (false일 때) 에러를 발생시킨다.
revert: 조건없이 에러를 발생시키고, gas를 환불시켜준다.
require: 특정한 조건에 부합하지 않으면(false일 때) 에러를 발생시키고, gas를 환불시켜준다.
*/
/*
0.8.0. 포함X
0.8.1~
assert: 오직 내부적 에러 테스트 용도, 불변성 체크용도.
assert가 에러를 발생시키면, panic(uint256)이라는 에러타입의 에러 발생
*/
contract lec21 {
//0.7.0.ver(3000000 gas) // 0.8.x.ver(21232 gas) : test용
function assertNow() public pure {
assert(false);
}
//0.7.0.ver(21344 gas) // 0.8.x.ver(21520 gas) 예상가스비용지불하고, revert에 걸려서 나머지는 환불
function revertNow() public pure {
revert("error!!");//무조건 에러를 뱉으니까 실현적이지 않아서, if나 require(=if+revert)를 쓴다
}
//0.7.0.ver(21338 gas) // 0.8.x.ver(21520 gas)
function requireNow() public pure {
require(false, "occurred");
}
function onlyAdults(uint256 _age) public pure returns(string memory) {
if(_age < 19) { //if문은 true일때 revert가 작동하지만
revert("You are not allowed to pay for the cigarette");
}
return "Tour payment is acceeded";
}
//require문은 false일때 revert가 작동하다
function onlyAdults2(uint256 _age) public pure returns (string memory) {
require(_age>19,"You are not allowed to pay for the cigarette" );
return "Tour payment is acceeded";
}
}
try-catch문
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
/*
0.6 버전 이후
try/catch 왜 써야하는가?
기존의 에러 핸들러 assert/revert/require는 에러를 발생시키고 프로그램을 끝냄
그러나, try/catch로 에러가 났어도, "프로그램을 종료시키지않고 어떠한 대처를 하게" 만들 수 있다.
trh/catch의 특징
1.
try/catch문 안에서, assert/revert/require을 통해 에러가 난다면 catch는 에러를 잡지 못하고,
개발자가 의도한지 알고 정상적으로 프로그램을 끝낸다.
try/catch문 밖에서,⭐️assert/revert/require을 통해 에러가 난다면 catch는 에러를 잡고, 에러를 핸들할 수 있다
2. 3가지 catch
catch Error(string memory reason) {...} : revert나 require를 통해 생성된 에러용도
catch Panic(uint errorCode) {...} : assert를 통해 생성된 에러가 날 때 이 catch에 잡힌다.
(errorCode는 솔리디티이 정의 Panic에러에서 확인 - 0.8.1 버전부터 있다)
catch(bytesmemoryLowLevelData){...} : 이 catch는 로우 레벨에러를 잡는다.
3. 어디서 쓰는가?
외부 스마트 컨트랙을 함수로 부를 때 : 다른 스컨을 인스턴스화 해서, try/catch문이 있는 스컨의 함수를 불러와서 사용.
외부 스마트 컨트랙을 생성할 때 : 다른 스컨을 인스턴스화 생성 할 때 씀.
스컨 내에서 함수를 부를 때 : this를 통해 try/catch를 씀
*/
contract math {
function division(uint256 _num1, uint256 _num2) public pure returns (uint256) {
require(_num1<10, "num1 shoud not be more than 10"); //10이상일때 에러발생
return _num1/_num2;
}
}
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(); //위의 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) { //_num1이 10이상인경우
emit catchErr("revert/require", _err);
return (0, false);
}catch Panic(uint256 _errorCode){ //_num2가 0인경우 //0.8.1.ver에서만 확인가능하다
emit catchPanic("asserError/Panic", _errorCode);
return(0,false);
}catch (bytes memory _errorCode) {
emit catchLowLevelErr("LowlevelError", _errorCode);
return(0,false);
}
}
}
'Block Chain' 카테고리의 다른 글
[solidity] modifier (feat.솔리디티깨부수기) (0) | 2022.12.05 |
---|---|
[solidity] return/SPDX (feat.솔리디티깨부수기) (0) | 2022.12.05 |
[solidity] if문/반복문/continue와break/equal (feat.솔리디티깨부수기) (0) | 2022.12.05 |
[solidity] struct구조체 (feat.솔리디티깨부수기) (0) | 2022.11.30 |
[solidity] mapping/array (feat.솔리디티깨부수기) (11) | 2022.11.29 |
Comments