Перейти к основному контенту

Переводы и одобрение токенов ERC-20 из смарт-контракта на Solidity

смарт-контракты
токены
solidity
erc-20
Средний уровень
jdourlens
7 апреля 2020 г.
6 минут на чтение

В предыдущем руководстве мы изучили анатомию токена ERC-20 на Solidity в блокчейне Эфириума. В этой статье мы посмотрим, как можно использовать смарт-контракт для взаимодействия с токеном с помощью языка Solidity.

Для этого смарт-контракта мы создадим настоящую учебную децентрализованную биржу (DEX), где пользователь сможет обменивать эфир на наш недавно развернутый токен ERC-20.

В этом руководстве мы будем использовать код, написанный в предыдущем руководстве, в качестве основы. Наша DEX создаст экземпляр контракта в своем конструкторе и будет выполнять следующие операции:

  • обмен токенов на эфир
  • обмен эфира на токены

Мы начнем писать код нашей децентрализованной биржи с добавления простой кодовой базы ERC-20:

Наш новый смарт-контракт DEX развернет ERC-20 и получит все выпущенные токены:

Итак, теперь у нас есть наша DEX, и ей доступен весь резерв токенов. Контракт имеет две функции:

  • buy: Пользователь может отправить эфир и получить взамен токены
  • sell: Пользователь может решить отправить токены, чтобы получить эфир обратно

Функция покупки (buy)

Давайте напишем функцию покупки. Сначала нам нужно будет проверить количество эфира, которое содержит сообщение, и убедиться, что контракт владеет достаточным количеством токенов, а также что в сообщении есть немного эфира. Если контракт владеет достаточным количеством токенов, он отправит это количество токенов пользователю и сгенерирует событие Bought.

Обратите внимание, что если мы вызовем оператор require, то в случае ошибки транзакция откатится, а отправленный эфир будет возвращен пользователю.

Для простоты мы просто обмениваем 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. Одобрение перевода требует, чтобы пользователь вызвал токен ERC20Basic, экземпляр которого создан DEX. Этого можно достичь, сначала вызвав функцию token() контракта DEX, чтобы получить адрес, по которому DEX развернула контракт ERC20Basic под названием token. Затем мы создаем экземпляр этого контракта в нашей сессии и вызываем его функцию approve. После этого мы сможем вызвать функцию sell контракта DEX и обменять наши токены обратно на эфир. Например, вот как это выглядит в интерактивной сессии Brownie:

Затем, когда вызывается функция продажи, мы проверим, был ли успешен перевод с адреса вызывающей стороны на адрес контракта, а затем отправим эфир обратно на адрес вызывающей стороны.

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 события (Transfer и Sold) в транзакции, а ваш баланс токенов и баланс эфира обновятся.

Two events in the transaction: Transfer and Sold


Из этого руководства мы узнали, как проверять баланс и разрешение токена ERC-20, а также как вызывать Transfer и TransferFrom смарт-контракта ERC-20 с использованием интерфейса.

После того как вы совершите транзакцию, у нас есть руководство по JavaScript о том, как дождаться и получить подробную информацию о транзакциях (opens in a new tab), которые были выполнены в вашем контракте, а также руководство по декодированию событий, сгенерированных переводами токенов или любыми другими событиями (opens in a new tab), при условии, что у вас есть ABI.

Вот полный код для этого руководства: