[Ethers Js 겉핥기] #1. 기본 용어

toto9602·2023년 10월 22일
0

Ethers js

목록 보기
2/5

본 시리즈에서는, 블록체인과 스마트 컨트랙트가 어떤 건지도 전혀 모르던 어느 주니어가..
약 1년간 스마트 컨트랙트를 호출하는 서버 작업을 접하며 우당탕탕 습득한,
ethers js 라이브러리 활용에 관한 이야기를 담을 예정입니다.

어디까지나 라이브러리 사용에 중점을 둘 예정이기에,
블록체인, 스마트 컨트랙트, EVM 등에 대한 기술적인 깊이를 얻고자 하는 분들을 위한 글은 아닐 것임을 밝힙니다.. 🙇

🙇 잘못된 내용에 대한 지적은 항상 감사드립니다!!

💡 본 시리즈의 모든 내용은 ethers js v5를 기준으로 작성되었습니다.

❗ 작성일(2023.10.22) 기준 6.8.0버전까지 공개된 ethers js v6와 상이한 내용이 있을 수 있습니다!

💡 본 포스팅에서는 ethers js로 블록체인과 상호작용하기 위해 일반적으로 사용되는 Provider , Signer , InterfaceContract 클래스에 대한 기본적인 개념을 담으려 합니다.

참고 자료

ethers js 공식 문서
Ethereum Docs
Solidity By Examples
솔리디티 기본 문법

Ethers Js란?

[ 공식 문서 설명 ]

The ethers.js library aims to be a complete and compact library for interacting with the Ethereum Blockchain and its ecosystem.

이더리움 블록체인과 상호작용하기 위한 라이브러리!

| 이더리움뿐만 아니라, EVM(Ethereum Virtual Machine, 이더리움 가상 머신) 기반으로 만들어진 대부분의 체인에 사용이 가능합니다!

Provider 클래스

[ 공식 문서 설명 ]

A Provider (in ethers) is a class which provides an abstraction for a connection to the Ethereum Network. It provides read-only access to the Blockchain and its status.

  • Provider란 네트워크(체인)과의 연결을 추상화한 Class입니다.
  • Provider 클래스로 블록체인에 대한 read-only 함수를 호출할 수 있습니다.

cf. read-only 함수?

  • 스마트 컨트랙트 개발에 많이 사용되는 Solidity 프로그래밍 언어에서 함수를 작성할 때에는, 함수의 가시성(Visibility)함수의 상태 변경성(State Mutability)를 선언합니다.

  • 이 중, read-only 접근과 관련되는 함수의 상태 변경성(State Mutability) 에는 크게 아래 3가지 유형이 있습니다.

    • view → read-only
    • pure → read-only
    • payable → state-mutable
  • Provider 가 read-only라는 것은, Provider 객체만으로는 Solidity 함수의 3가지 상태 변경 유형 중 viewpure 함수만을 호출할 수 있다는 의미입니다.

함수의 가시성(Visibility) 에 관하여서는, 추후 실제 스마트 컨트랙트 호출에 관한 내용을 다룰 때 함께 언급하려 합니다. 🙇

cf. View 함수

[ 예시 (from. SolidityByExample) ]

contract ViewAndPure {
    uint public x = 1;

    // Promise not to modify the state.
    function addToX(uint y) public view returns (uint) {
        return x + y;
    }
    ...
 }

→ 함수 밖에서 선언한 변수를 뜻하는 상태 변수(State variable) (여기서는 x)를 실행 과정에서 변경하지 않는 함수,
즉, 체인의 상태를 변경하지 않는 함수view 유형을 사용할 수 있습니다.

cf. Pure 함수

[ 예시 (from. SolidityByExample) ]

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

contract ViewAndPure {
    uint public x = 1;
	... 
    // Promise not to modify or read from the state.
    function add(uint i, uint j) public pure returns (uint) {
        return i + j;
    }
}

→ 상태 변수의 변경(즉, 체인의 상태 변경)도, 체인의 상태를 읽어오지도 않는 함수에 pure 유형을 사용할 수 있습니다.

cf. Payable 함수

→ 실행 과정에서 토큰을 송/수신할 수 있는 함수에 payable 유형을 사용합니다.

Provider 클래스의 생성

ethers js 공식 문서는 DefaultProvider를 사용하여 Provider에 여러 service를 연결하는 것을 권장하고 있지만, 본 포스팅 및 시리즈에서는 역시 ethers js 문서에서 많이 사용되는 방법으로 언급된 JsonRpcProvider를 사용할 예정입니다!

JsonRpcProvider

→ URL 등으로 JSON-RPC HTTP API에 연결하는 Provider

cf. JSON-RPC API란?

→ 클라이언트와 블록체인 노드가 통신하기 위한 규약으로, JSON 데이터 형식을 사용!

[ JsonRpcProvider 클래스 초기화 ]

const provider = new ethers.providers.JsonRpcProvider(`${API_URL}`);

Signer 클래스

[ 공식 문서 설명 ]

A Signer is a class which (usually) in some way directly or indirectly has access to a private key, which can sign messages and transactions to authorize the network to charge your account ether to perform operations.

  • 직/간접적으로 사용자의 지갑 개인 키에 접근 권한을 갖고, 사용자 account의 ETH를 차감할 권한을 네트워크에 부여하기 위해, 트랜잭션에 서명할 수 있는 클래스
  • Signer 자체는 추상 클래스이므로, Wallet, VoidSigner, JsonRpcSigner 등의 구현체 sub-class를 이용해야 합니다.
    ( 대표적으로는 Wallet 클래스를 사용하는 것 같습니다 )

→ 초기화 과정에서 사용자의 지갑 개인 키를 주입받아,
트랜잭션 실행 과정에서 사용자가 가진 자산을 사용할 수 있도록 트랜잭션에 서명을 진행합니다.

→ 이를 통해, Provider 와 달리 블록체인의 상태를 변경하는 함수 역시 호출이 가능합니다.
(혹시 개념이 낯서신 분들을 위해,
사용자는 블록체인의 상태를 변경하는 트랜잭션을 전송할 때, 일정한 양의 토큰을 지불하며 이를 가스비(gas)라 합니다)

Signer 클래스 구현체 생성

Wallet

→ EOA(External Owned Account, 사용자의 지갑)의 개인 키로 트랜잭션 및 메시지에 서명하는 클래스

[ Wallet 클래스의 초기화 ]

// RPC_URL을 주입받은 provider 클래스를 생성합니다.
const provider = new ethers.providers.JsonRpcProvider(`${API_URL}`);

// 지갑의 개인 키와, provider 클래스를 주입하여 Signer 클래스를 생성합니다. 
const wallet = new ethers.Wallet(`${EOA_PRIVATE_KEY}`, provider);

Interface 클래스

The Interface Class abstracts the encoding and decoding required to interact with contracts on the Ethereum network.

  • 네트워크의 스마트 컨트랙트와 상호작용하기 위한 인코딩 및 디코딩을 추상화합니다.

→ 스마트 컨트랙트를 네트워크에 배포하면, 배포된 컨트랙트 주소와 함께, 스마트 컨트랙트에 작성된 함수 등을 정의한 인터페이스 정보가 담긴 파일이 반환되는데, 이를 ABI(Application Binary Interface)라 합니다.

[ ABI 예시 (from. Ethers js Docs) ]

[
  	{
      "type":"function",
     "name":"transferFrom",
      "constant":false,
      "payable":false,
      "inputs":[
        {
          "type":"address",
          "name":"from"
        },
        {
          "type":"address",
          "name":"to"
        },
        {
          "type":"uint256",
          "name":"amount"
        }
      ],
      "outputs":[]
    }
]  
  • 다만, 스마트 컨트랙트가 기반을 두고 있는 EVM은, 그 자체로는 이 ABI 파일을 이해할 수 없습니다.
  • 따라서, Interface 클래스는 ABI를 통해, 실행하고자 하는 함수를 EVM이 이해할 수 있는 형태로 인코딩하여 전송하고, 반환된 결과를 개발자가 이해할 수 있는 형태로 디코딩하는 역할을 담당합니다.

Interface 클래스의 생성


const ABI = abi; //abi는 위의 예시와 같이 배열 형태를 가집니다. 
const iface = new ethers.utils.Interface(ABI);

Contract 클래스

[ 공식 문서 설명 ]

A Contract is an abstraction which represents a connection to a specific contract on the Ethereum Network, so that applications can use it like a normal JavaScript object.

→ 특정한 컨트랙트와의 연결을 추상화한 클래스로, 이를 통해 스마트 컨트랙트와의 상호작용을 일반적인 Javascript 객체를 사용하듯이 진행할 수 있습니다.

Contract 클래스의 생성

// Provider 클래스를 생성
const provider = new ethers.providers.JsonRpcProvider(`${API_URL}`);

// Signer 클래스를 생성
const wallet = new ethers.Wallet(`${PRIVATE_KEY}`, provider);

const contract = new Contract(`${CONTRACT_ADDRESS}`, ABI, signer) // signer 또는 provider
profile
주니어 백엔드 개발자입니다! 조용한 시간에 읽고 쓰는 것을 좋아합니다 :)

0개의 댓글