본문 바로가기
블록체인교육/솔리디티

[솔리디티] 13. Try Catch, import(임포트), library(라이브러리)

by Danny_Kim 2022. 6. 15.

[NEW] 누구나 쉽게 따라하는 솔리디티 강의(솔리디티 버전 0.8.13)

1. Helloworld, 카운터컨트랙트, 데이터타입

2. 변수, 상수, 불변, 상태변수 읽고 쓰기

3. 이더 단위, 가스와 가스가격

4. 조건문, 반복문, 맵핑(mapping)

5. 배열, 열거형(enum), 구조체(calldata,memory) 

6. 데이터 저장공간, 함수(view,pure 속성)

7. 에러(error), 함수수정자(modifier)

8. 이벤트(events), 생성자(constructor), 상속

9. 상속, 섀도잉,super키워드 함수 속성들

10. 인터페이스(interface), payable, 이더전송,받기 관련

11. Fallback, Call, Delegate(솔리디티 업그레이드 기법)

12. 함수 선택자(function selector), 다른 컨트랙트 사용 및 생성기법

13. Try Catch, Import(임포트), Library(라이브러리)

14. ABI 디코드, hash 함수, 서명검증, 가스최적화

 

 

1. Try Catch

 - try catch문은 컨트랙트 external 함수 호출시 에러를 확인할 수 있다.

 

예제) External contract로 사용할 Foo 컨트랙트를 아래와 같이 작성한다.

- Try Catch 문을 사용할 예제를 아래와 같이 작성하고, 테스트 값을 넣어서 테스트해본다.

 tryCatchExternalcall 함수에는 0, 1 넣고 테스트

 tryCatchNewContract 함수에는 아래의 값 넣고 테스트

// tryCatchNewContract(0x0000000000000000000000000000000000000000) => Log("invalid address")
// tryCatchNewContract(0x0000000000000000000000000000000000000001) => LogBytes("")
// tryCatchNewContract(0x0000000000000000000000000000000000000002) => Log("Foo created")

 

전체소스

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

// External contract used for try / catch examples
contract Foo {
    address public owner;

    constructor(address _owner) {
        require(_owner != address(0), "invalid address");
        assert(_owner != 0x0000000000000000000000000000000000000001);
        owner = _owner;
    }

    function myFunc(uint x) public pure returns (string memory) {
        require(x != 0, "require failed");
        return "my func was called";
    }
}

contract Bar {
    event Log(string message);
    event LogBytes(bytes data);

    Foo public foo;

    constructor() {
        // This Foo contract is used for example of try catch with external call
        foo = new Foo(msg.sender);
    }

    // Example of try / catch with external call
    // tryCatchExternalCall(0) => Log("external call failed")
    // tryCatchExternalCall(1) => Log("my func was called")
    function tryCatchExternalCall(uint _i) public {
        try foo.myFunc(_i) returns (string memory result) {
            emit Log(result);
        } catch {
            emit Log("external call failed");
        }
    }

    // Example of try / catch with contract creation
    // tryCatchNewContract(0x0000000000000000000000000000000000000000) => Log("invalid address")
    // tryCatchNewContract(0x0000000000000000000000000000000000000001) => LogBytes("")
    // tryCatchNewContract(0x0000000000000000000000000000000000000002) => Log("Foo created")
    function tryCatchNewContract(address _owner) public {
        try new Foo(_owner) returns (Foo foo) {
            // you can use variable foo here
            emit Log("Foo created");
        } catch Error(string memory reason) {
            // catch failing revert() and require()
            emit Log(reason);
        } catch (bytes memory reason) {
            // catch failing assert()
            emit LogBytes(reason);
        }
    }
}

 

2. Import

 - 로컬이나 외부에 있는 파일을 import할 수 있음.

 - 로컬 디렉토리에 아래와 같은 파일이 있다면,

   Import.sol

   Foo.sol

 

- Foo.sol 파일

Import.sol 파일

 - import를 사용하여 아래와 같이 Foo.sol을 가져와서 사용할 수 있음

 - 방법은 아래 예시 참고.

External)

 - Github에 있는 sol 파일을 아래와 같이 불러와서 사용할 수 있음.

 

 

3. Library(라이브러리)

 - 라이브러리는 컨트랙트와 유사하지만 상태변수(state variable)을 선언하거나 이더를 보낼 수 없음

 - 라이브러리가 컨트랙트 안에 포함된 경우 모든 라이브러리 함수는 internal(내부)로 적용됨

 - 컨트랙트가 배포되기 전에 라이브러리가 먼저 배포되고 연결되어야 함.

 - SafeMath와 Math를 library로 작성.

 - safemath는 덧셈시 overflow를 방지, sqrt는 제곱근 반환.

- 사용

- Array Library 예제

- 인덱스에서 요소를 삭제하고 배열을 재구성하는 배열함수

- 요소 사이에 간격이 없도록 함.

- 테스트 예제

전체소스

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

library SafeMath {
    function add(uint x, uint y) internal pure returns (uint) {
        uint z = x + y;
        require(z >= x, "uint overflow");

        return z;
    }
}

library Math {
    function sqrt(uint y) internal pure returns (uint z) {
        if (y > 3) {
            z = y;
            uint x = y / 2 + 1;
            while (x < z) {
                z = x;
                x = (y / x + x) / 2;
            }
        } else if (y != 0) {
            z = 1;
        }
        // else z = 0 (default value)
    }
}

contract TestSafeMath {
    using SafeMath for uint;

    uint public MAX_UINT = 2**256 - 1;

    function testAdd(uint x, uint y) public pure returns (uint) {
        return x.add(y);
    }

    function testSquareRoot(uint x) public pure returns (uint) {
        return Math.sqrt(x);
    }
}

// Array function to delete element at index and re-organize the array
// so that their are no gaps between the elements.
library Array {
    function remove(uint[] storage arr, uint index) public {
        // Move the last element into the place to delete
        require(arr.length > 0, "Can't remove from empty array");
        arr[index] = arr[arr.length - 1];
        arr.pop();
    }
}

contract TestArray {
    using Array for uint[];

    uint[] public arr;

    function testArrayRemove() public {
        for (uint i = 0; i < 3; i++) {
            arr.push(i);
        }

        arr.remove(1);

        assert(arr.length == 2);
        assert(arr[0] == 0);
        assert(arr[1] == 2);
    }
}

 

소스출처 : https://solidity-by-example.org/

 

블록체인 교육 문의는 아래 링크 참고 바랍니다. 

https://kimsfamily.kr/414

 

블록체인 교육 커리큘럼 및 프로필

안녕하세요 제 프로필을 간략하게 정리하였습니다. 비즈니스 문의는 dannykim@kakao.com 으로 연락주시기 바랍니다. 감사합니다. 프로필) 블록체인 강의 경력) 1. 블록체인 강의 (20년~현재) 2022년  -

kimsfamily.kr

 

반응형

댓글0