본문으로 건너뛰기

Solidity 스마트 컨트랙트에서 ERC-20 토큰 전송 및 승인

스마트 컨트랙트
토큰
Solidity
erc-20
중급
jdourlens
2020년 4월 7일
10 분 소요

이전 튜토리얼에서는 이더리움 블록체인에서 Solidity로 작성된 ERC-20 토큰의 구조를 살펴보았습니다. 이 글에서는 Solidity 언어를 사용하여 스마트 컨트랙트로 토큰과 상호작용하는 방법을 알아보겠습니다.

이 스마트 컨트랙트를 위해, 사용자가 이더를 새로 배포된 ERC-20 토큰으로 거래할 수 있는 실제 더미 탈중앙화 거래소(DEX)를 만들 것입니다.

이 튜토리얼에서는 이전 튜토리얼에서 작성한 코드를 기반으로 사용합니다. 우리의 DEX는 생성자에서 컨트랙트 인스턴스를 인스턴스화하고 다음 작업을 수행합니다.

  • 토큰을 이더로 교환
  • 이더를 토큰으로 교환

간단한 ERC20 코드베이스를 추가하여 탈중앙화 거래소 코드를 시작하겠습니다.

우리의 새로운 DEX 스마트 컨트랙트는 ERC-20을 배포하고 공급된 모든 토큰을 가져옵니다.

이제 DEX가 준비되었으며 사용 가능한 모든 토큰 예비량을 보유하고 있습니다. 이 컨트랙트에는 두 가지 함수가 있습니다.

  • buy: 사용자는 이더를 전송하고 그 대가로 토큰을 받을 수 있습니다.
  • sell: 사용자는 토큰을 전송하고 이더를 돌려받기로 결정할 수 있습니다.

buy 함수

buy 함수를 코딩해 보겠습니다. 먼저 메시지에 포함된 이더의 양을 확인하고, 컨트랙트가 충분한 토큰을 소유하고 있는지, 그리고 메시지에 이더가 포함되어 있는지 검증해야 합니다. 컨트랙트가 충분한 토큰을 소유하고 있다면 사용자에게 해당 수량의 토큰을 전송하고 Bought 이벤트를 발생시킵니다.

오류가 발생하여 require문을 호출하는 경우, 전송된 이더는 즉시 되돌려져(revert) 사용자에게 반환된다는 점에 유의하세요.

간단하게 설명하기 위해 1 토큰을 1 Wei로 교환하겠습니다.

function buy() payable public {
    uint256 amountTobuy = msg.value;
    uint256 dexBalance = token.balanceOf(address(this));
    require(amountTobuy > 0, "You need to send some ether");
    require(amountTobuy <= dexBalance, "Not enough tokens in the reserve");
    token.transfer(msg.sender, amountTobuy);
    emit Bought(amountTobuy);
}

구매가 성공적으로 이루어진 경우 트랜잭션에서 두 가지 이벤트를 확인할 수 있습니다. 토큰 Transfer 이벤트와 Bought 이벤트입니다.

Two events in the transaction: Transfer and Bought

sell 함수

판매를 담당하는 함수는 먼저 사용자가 사전에 approve 함수를 호출하여 해당 금액을 승인하도록 요구합니다. 전송을 승인하려면 사용자가 DEX에 의해 인스턴스화된 ERC20Basic 토큰을 호출해야 합니다. 이는 먼저 DEX 컨트랙트의 token() 함수를 호출하여 DEX가 token라는 ERC20Basic 컨트랙트를 배포한 주소를 검색함으로써 달성할 수 있습니다. 그런 다음 세션에서 해당 컨트랙트의 인스턴스를 생성하고 approve 함수를 호출합니다. 이후 DEX의 sell 함수를 호출하여 토큰을 다시 이더로 스왑할 수 있습니다. 예를 들어, 대화형 Brownie 세션에서는 다음과 같이 보입니다.

그런 다음 sell 함수가 호출되면, 호출자 주소에서 컨트랙트 주소로의 전송이 성공했는지 확인한 후 이더를 호출자 주소로 다시 보냅니다.

function sell(uint256 amount) public {
    require(amount > 0, "You need to sell at least some tokens");
    uint256 allowance = token.allowance(msg.sender, address(this));
    require(allowance >= amount, "Check the token allowance");
    token.transferFrom(msg.sender, address(this), amount);
    payable(msg.sender).transfer(amount);
    emit Sold(amount);
}

모든 것이 정상적으로 작동하면 트랜잭션에서 2개의 이벤트(TransferSold)가 표시되고 토큰 잔액과 이더 잔액이 업데이트된 것을 확인할 수 있습니다.

Two events in the transaction: Transfer and Sold


이 튜토리얼을 통해 ERC-20 토큰의 잔액과 허용량을 확인하는 방법과 인터페이스를 사용하여 ERC20 스마트 컨트랙트의 TransferTransferFrom를 호출하는 방법을 살펴보았습니다.

트랜잭션을 생성한 후에는 컨트랙트에서 발생한 트랜잭션을 대기하고 세부 정보를 가져오는 (opens in a new tab) JavaScript 튜토리얼과, ABI가 있는 한 토큰 전송이나 기타 이벤트에 의해 생성된 이벤트를 디코딩하는 튜토리얼 (opens in a new tab)이 준비되어 있습니다.

다음은 이 튜토리얼의 전체 코드입니다.