Přejít na hlavní obsah

Převody a schvalování tokenů ERC-20 z chytrého kontraktu v Solidity

chytré kontrakty
tokeny
Solidity
erc-20
Středně pokročilý
jdourlens
7. dubna 2020
6 minut čtení

V předchozím tutoriálu jsme studovali anatomii tokenu ERC-20 v Solidity na blockchainu Etherea. V tomto článku se podíváme, jak můžeme použít chytrý kontrakt k interakci s tokenem pomocí jazyka Solidity.

Pro tento chytrý kontrakt vytvoříme skutečnou cvičnou decentralizovanou burzu (DEX), kde může uživatel směnit ether za náš nově nasazený token ERC-20.

Pro tento tutoriál použijeme jako základ kód, který jsme napsali v předchozím tutoriálu. Naše DEX vytvoří instanci kontraktu ve svém konstruktoru a bude provádět následující operace:

  • směna tokenů za ether
  • směna etheru za tokeny

Kód naší decentralizované burzy začneme přidáním naší jednoduché kódové základny ERC-20:

Náš nový chytrý kontrakt DEX nasadí ERC-20 a získá veškerou zásobu:

Nyní tedy máme naši DEX a ta má k dispozici celou rezervu tokenů. Kontrakt má dvě funkce:

  • buy: Uživatel může poslat ether a získat výměnou tokeny
  • sell: Uživatel se může rozhodnout poslat tokeny a získat zpět ether

Funkce buy

Pojďme naprogramovat funkci buy. Nejprve budeme muset zkontrolovat množství etheru, které zpráva obsahuje, a ověřit, že kontrakt vlastní dostatek tokenů a že zpráva obsahuje nějaký ether. Pokud kontrakt vlastní dostatek tokenů, pošle uživateli odpovídající počet tokenů a vyvolá událost Bought.

Všimněte si, že pokud v případě chyby zavoláme funkci require, odeslaný ether bude okamžitě vrácen (reverted) a předán zpět uživateli.

Abychom to udrželi jednoduché, směníme prostě 1 token za 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);
}

V případě, že je nákup úspěšný, měli bychom v transakci vidět dvě události: Transfer tokenu a událost Bought.

Two events in the transaction: Transfer and Bought

Funkce sell

Funkce zodpovědná za prodej bude nejprve vyžadovat, aby uživatel předem schválil částku zavoláním funkce approve. Schválení převodu vyžaduje, aby uživatel zavolal token ERC20Basic, jehož instanci vytvořila DEX. Toho lze dosáhnout tak, že nejprve zavoláme funkci token() kontraktu DEX, abychom získali adresu, na které DEX nasadila kontrakt ERC20Basic s názvem token. Poté v naší relaci vytvoříme instanci tohoto kontraktu a zavoláme jeho funkci approve. Následně můžeme zavolat funkci sell naší DEX a provést swap našich tokenů zpět za ether. Takto to například vypadá v interaktivní relaci Brownie:

Když je pak zavolána funkce sell, zkontrolujeme, zda byl převod z adresy volajícího na adresu kontraktu úspěšný, a poté pošleme ethery zpět na adresu volajícího.

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);
}

Pokud vše funguje, měli byste v transakci vidět 2 události (Transfer a Sold) a váš zůstatek tokenů i etheru by se měl aktualizovat.

Two events in the transaction: Transfer and Sold


V tomto tutoriálu jsme viděli, jak zkontrolovat zůstatek a povolený limit tokenu ERC-20 a také jak pomocí rozhraní zavolat Transfer a TransferFrom chytrého kontraktu ERC-20.

Jakmile provedete transakci, máme tutoriál v JavaScriptu, jak počkat a získat podrobnosti o transakcích (opens in a new tab), které byly provedeny s vaším kontraktem, a tutoriál pro dekódování událostí generovaných převody tokenů nebo jakýmikoli jinými událostmi (opens in a new tab), pokud máte ABI.

Zde je kompletní kód pro tento tutoriál: