Перейти до основного вмісту

Перекази та схвалення токенів 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

Давайте напишемо код функції 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:

Потім, коли викликається функція 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 події (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.

Ось повний код для цього посібника: