[Solidity] import, Library

jhcha·2023년 8월 5일
0

Solidity

목록 보기
11/17
post-thumbnail

import

url: https://solidity-by-example.org/import/

// folder structure
├── Import.sol
└── Foo.sol

Foo.sol


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

struct Point {
    uint x;
    uint y;
}

error Unauthorized(address caller);

function add(uint x, uint y) pure returns (uint) {
    return x + y;
}

contract Foo {
    string public name = "Foo";
}

Import.sol

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

// import Foo.sol from current directory
import "./Foo.sol";

// import {symbol1 as alias, symbol2} from "filename";
import {Unauthorized, add as func, Point} from "./Foo.sol";

contract Import {
    // Initialize Foo.sol
    Foo public foo = new Foo();

    // Test Foo.sol by getting it's name.
    function getFooName() public view returns (string memory) {
        return foo.name();
    }
}


리믹스에서는 왼쪽 파일 탭에서 New File을 통해 여러개의 파일을 생성할 수 있다.
Import.sol를 배포하면 Foo 컨트랙트가 생성되어 주소를 확인할 수 있다. 마찬가지로 getFooName()을 통해 foo 컨트랙트의 상태 변수 값도 조회할 수 있다.

// https://github.com/owner/repo/blob/branch/path/to/Contract.sol
import "https://github.com/owner/repo/blob/branch/path/to/Contract.sol";

// Example import ECDSA.sol from openzeppelin-contract repo, release-v4.5 branch
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.5/contracts/utils/cryptography/ECDSA.sol
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.5/contracts/utils/cryptography/ECDSA.sol";

추가적으로 GitHub url을 직접 import 하는 것도 가능하다.

Library

url: https://solidity-by-example.org/library/

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

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 TestMath {
    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 there 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);
    }
}

라이브러리는 컨트랙트와 유사하지만, 상태 변수를 선언하거나 이더를 보내는 것이 불가능하다.
라이브러리 function이 internal인 경우 라이브러리는 컨트랙트 안에 임베드된다. 아닌 경우, 컨트랙트를 배포하기 전에 라이브러리를 배포하고 연결해야 한다.

using Array for uint[];

Array 라이브러리를 uint[] 형태로 사용한다는 의미이다. using 키워드를 통한 선언으로 인해 uint[] 타입의 변수에서 Array 라이브러리의 함수를 사용할 수 있다.

uint[] public arr;
arr.remove(1);

따라서, uint[] arr에서 Array 라이브러리의 remove funtion를 사용할 수 있다.

0개의 댓글