[Web3.0] ethers.js를 사용하여 Blockchain API만들기

twilight8·2023년 1월 29일
0
post-thumbnail

ethers.js는 javascript에서 Ethereum Blockchain에 접근할 수 있는 라이브러리 중 하나다. 그리고 Infura라는 Blockchain API를 제공하는 써드파티 툴을 사용하여 블록체인에 접근할 수 있는 API를 만들어 보겠다.

1. Install ethers.js

먼저 ethers.js 패키지를 설치한다.

npm install ethers

2. import ethers.js

그리고 ethers 패키지를 import한 후 Blockchain API를 사용하기 위해 JsonRpcProvider()메서드로 infura의 endpoint를 호출해 준다.

const { ethers } require = ("ethers")

const provider = new ethers.providers.JsonRpcProvider(`https://sepolia.infura.io/v3/${INFURA_ID}`)

Json RPC

Json RPC는 JSON으로 인코딩된 Remote Procedure Call 이다.

특징

  • 4계층 TCP에서 동작하여 다양한 프로토콜에서 사용할 수 있다.
  • HTTP에서 동작하는 경우 하나의 Method를 통해 통신한다.
  • POST요청에서 body로 json을 넘기는데 JsonRPC 포맷을 따른다.
  • CURD를 포함한 다양한 action을 나타내는 작업을 표현할 수 있다.

3. ETH 잔액 조회 API

블록체인 API를 사용할 준비가 되었으니 지값주소를 parameter로 넘겨 해당 지갑 주소의 ETH잔액을 확인하는 API를 작성해보겠다.

exports.getEthBalance = async (req, res) => {
	try {
    	const INFURA_ID = process.env.INFURA_ID
        const privider = new ethers.providers.JsonRpcProvider(`https://mainnet.infura.io/v3/${INFURA_ID}`)
        
        const address = req.body.params
        
        const balance = await provider.getBalance(address)
        const ethBalance = {
        	ethBalance: ethers.utils.formatEther(balance)
        }
        
        res.send(ethBalance)
    } catch () {
    	res.sendStatus(500)
    }
}
  1. 비동기 처리를 위해 async/await를 사용.
  2. blockchain API를 사용하기 위해 Infura에 접근하여 ethers 객체를 provider 변수에 대입.
  3. 조회 하려는 지갑주소를 req.body.params에 담아 address 변수에 대입.
  4. blockchain API에서 잔액을 조회하는 getBalance() 메서드에 인자값으로 지갑 주소를 넣어 balance 변수에 대입
  5. 단위 조정을 위해 formatEther() 메서드에 인자값으로 balance값을 넣어준다.
  6. res.send()에 결과 값 ethBalance를 넣어 보내준다.


/api/ethereum/balacne 주소를 호출하면 getEthBalance()가 실행되게 router를 설정한다음 postman에서 호출한 모습을 보면 params에 담긴 지갑주소를 parameter로 보냈을 때 해당 지갑주소의 ETH 잔고가 출력되는 것을 볼 수 있다.

4. token 잔액 조회 API

이번에는 ERC20기반 token(ESG)의 잔액을 조회 하는 API를 만들어 보겠다.
ETH를 조회하는 api와 달리 token의 잔액을 조회하려면 해당 토큰의 contract의 함수를 사용해야 한다.
Solidity ABI를 Json형식이 아닌 Human-Readable ABI 형태로 작성해도 호환되기 때문에 따로 ABI Json파일을 불러오지 않고, 작성 중인 API에서 contract method를 호출한다.

// JSON ABI
const jsonAbi = `[
	{
    "type": "function",
    "name": "balanceOf",
    "constant":true,
    "stateMutability": "view",
    "payable":false, "inputs": [
      { "type": "address", "name": "owner"}
    ],
    "outputs": [
      { "type": "uint256"}
    ]
  },
]`;

// Human-Readable ABI
const humanReadableAbi = [
	"function balanceOf(address owner) view returns (uint balance)"
]

smart contract의 BalanceOf() 함수를 각각 Json ABI와 Human-Readable ABI로 작성한 모습이다.
Human-Readable ABI로 표현한 코드가 훨씬 간결하고 보기 쉽다는 것을 느낄 수 있다.
따라서, token 잔액 조회 API에서는 ETH 잔액조회에서 contract ABI를 불러오는 코드만 추가로 작성해주면 된다.

exports.getEsgBalance = async (req, res) => {
  try {
    const INFURA_ID = process.env.INFURA_ID
    const provider = new ethers.providers.JsonRpcProvider(`https://mainnet.infura.io/v3/${INFURA_ID}`) 
    
    const ERC20_ABI = [
      "function balanceOf(address) view returns (uint)",
    ];

    // ESG contract address
    const address = '0x20cD2E7Ec8F5d8b337fe46a4F565Ccef1561b9a9'
    const contract = new ethers.Contract(address, ERC20_ABI, provider)

    // wallet address
    const walletAddress = req.body.params
    const balance = await contract.balanceOf(walletAddress)

    const esgBalance = {
      esgBalance: ethers.utils.formatEther(balance)
    }

    res.send(esgBalance)
  } catch (err) {
    res.sendStatus(500)
  }
}

ERC20_ABI 배열에 사용하고자 하는 contract ABI를 Human-Readable 형식으로 추가해준다. 현재는 balanceOf() 함수만 추가되어 있지만 여러가지 함수를 배열의 원소로 추가해 줄 수 있다.

  1. 비동기 처리를 위해 async/await를 사용.
  2. blockchain API를 사용하기 위해 Infura에 접근하여 ethers 객체를 provider 변수에 대입.
  3. token contract 주소를 address 변수에 대입한다.
  4. contract 변수에 ethers.Contract()의 새로운 객체를 생성
  5. 조회 하려는 지갑주소를 req.body.params에 담아 address 변수에 대입.
  6. blockchain API에서 잔액을 조회하는 getBalance() 메서드에 인자값으로 지갑 주소를 넣어 balance 변수에 대입
  7. 단위 조정을 위해 formatEther() 메서드에 인자값으로 balance값을 넣어준다.
  8. res.send()에 결과 값 ethBalance를 넣어 보내준다.

코드는 ETH 잔액 조회하는 API에서 3, 4번 과정만 추가해주면 된다.
마찬가지로 api/esg/balance 주소를 호출하면 getEsgBalacne()를 호출하고, parameter로 지값주소를 넣어주면 아래와 같이 ESG토큰의 잔고가 출력되는 것을 볼 수 있다.

지금까지 Ethers.js 패키지와 Infura 사용하여 Ethereum 블록체인의 ETH와 ERC20 기반 token의 잔액을 조회하는 API를 작성해 보았다.
Ethers.js를 참고하여 잔액 조회 외에도 송금 기능 등 여러가지 API를 구현할 수 있으니 간단한 Web3.0 웹 페이지도 만들어 볼 수 있을 것 같다.


참고

https://docs.ethers.org/v5/
https://jepark-diary.tistory.com/79

profile
개발자의 성장기, 실패와 성공을 넘나드는 과정 속에서 발견하는 지혜의 조각들.

0개의 댓글