DeFi is momenteel een belangrijk onderwerp van discussie binnen de cryptocurrency-ruimte. DeFi staat voor “Decentralized finance” en betekent dat er geen centrale autoriteit is die de overdracht van geld bewaakt en controleert. Dit impliceert dat transacties in DeFi P2P zijn, wat betekent dat er geen centrale autoriteit verantwoordelijk is voor de overdracht en dat het geld rechtstreeks van de ene entiteit naar de andere wordt verzonden. In dit artikel leer je hoe je aan de slag kunt met DeFi door een full-stack DeFi-app op de Polygon-keten te maken met Next.js als frontend. Deze app verhandelt OKToken (een fictief token) van de gebruiker. Elke aankooptransactie vermindert echter één token van het aantal tokens dat men per MATIC kan krijgen (verkopen verhoogt dit aantal met één). Dit is geen ideale demonstratie, maar op deze manier kun je begrijpen hoe je eigen logica kunt gebruiken in slimme contracten van Solidity en leer je je eigen full-stack DeFi-app te maken met behulp van Polygon.
Inhoudsopgave
– Vereisten
– Het Hardhat-project creëren
– Onze slimme contracten maken
– Het implementeren van onze slimme contracten
Vereisten
Zorg ervoor dat je over het volgende beschikt om aan de slag te gaan met deze tutorial:
Het Hardhat-project creëren
Navigeer naar een veilige map en voer de volgende opdracht in de terminal uit om je Hardhat-project te initialiseren:
npx hardhat
Na het uitvoeren van deze opdracht, zal de volgende Hardhat-initialisatiewizard in de terminal verschijnen. Selecteer “Maak een geavanceerd voorbeeldproject” uit de lijst. Daarna wordt je gevraagd waar je het Hardhat-project wilt initialiseren; wijzig het veld niet, klik simpelweg op “Enter” zodat het project wordt geïnitialiseerd in de huidige map. Daarna wordt aan je gevraagd of je afhankelijkheden wilt installeren die nodig zijn om je Hardhat-project te laten werken. Klik op “j” omdat we deze afhankelijkheden nodig zullen hebben en het is het beste idee om ze nu te installeren. De installatie van afhankelijkheden wordt gestart en kan enkele seconden tot enkele minuten duren, afhankelijk van de machine die je gebruikt. Voer nu de volgende opdracht uit in de terminal om een andere afhankelijkheid te installeren die we nodig hebben om onze Solidity-contractontwikkeling te vergemakkelijken:
npm install @openzeppelin/contracts
OpenZeppelin biedt slimme contractstandaarden die we kunnen gebruiken in onze eigen slimme contracten om eenvoudig Ownable, ERC-20- en ERC-721-contracten te maken, en nog veel meer. Nadat de afhankelijkheden met succes zijn geïnstalleerd, open je de map in een code-editor. We gebruiken VS Code in deze tutorial. We gaan twee slimme contracten maken: het eerste wordt ons ERC-20-token zelf en het tweede wordt een leverancierscontract, dat het kopen en verkopen van deze tokens zal vergemakkelijken.
Onze slimme contracten maken
Ga nu naar de contracts-map en maak een nieuw Solidity-bestand genaamd OKToken.sol die ons ERC-20 tokencontract zal bevatten. Gebruik de volgende code voor dit bestand:
// SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.4;
import “@openzeppelin/contracts/token/ERC20/ERC20.sol”;
contract OKToken is ERC20 {
constructor() ERC20(“OKT”, “OKToken”){
_mint(msg.sender, 10000 * 10 ** 18);
}
}
In de bovenstaande code importeren we het ERC20.sol bestand van “@openzeppelin/contracts” waarmee we gemakkelijk aan de slag kunnen gaan met een ERC-20-token. We geven vervolgens in de constructor het symbool “OKT” en de naam “OKToken” voor onze token. Dat is alles voor het tokencontract! Laten we nu werken aan het leverancierscontract. Onder de contractmap, maak je een nieuw bestand genaamd OKVendor.sol met de volgende code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import “./OKToken.sol”;
import “@openzeppelin/contracts/access/Ownable.sol”;
contract OKVendor is Ownable {
OKToken yourToken;
uint256 public tokensPerNativeCurrency = 100;
event BuyTokens(address buyer, uint256 amountOfNativeCurrency, uint256 amountOfTokens);
constructor(address tokenAddress) {
yourToken = OKToken(tokenAddress);
}
function buyTokens() public payable returns (uint256 tokenAmount) {
require(msg.value > 0, “You need to send some NativeCurrency to proceed”);
uint256 amountToBuy = msg.value * tokensPerNativeCurrency;
uint256 vendorBalance = yourToken.balanceOf(address(this));
require(vendorBalance >= amountToBuy, “Vendor contract has not enough tokens to perform transaction”);
(bool sent) = yourToken.transfer(msg.sender, amountToBuy);
require(sent, “Failed to transfer token to user”);
tokensPerNativeCurrency = tokensPerNativeCurrency – 1;
emit BuyTokens(msg.sender, msg.value, amountToBuy);
return amountToBuy;
}
function sellTokens(uint256 tokenAmountToSell) public {
require(tokenAmountToSell > 0, “Specify an amount of token greater than zero”);
uint256 userBalance = yourToken.balanceOf(msg.sender);
require(userBalance >= tokenAmountToSell, “You have insufficient tokens”);
uint256 amountOfNativeCurrencyToTransfer = tokenAmountToSell / tokensPerNativeCurrency;
uint256 ownerNativeCurrencyBalance = address(this).balance;
require(ownerNativeCurrencyBalance >= amountOfNativeCurrencyToTransfer, “Vendor has insufficient funds”);
(bool sent) = yourToken.transferFrom(msg.sender, address(this), tokenAmountToSell);
require(sent, “Failed to transfer tokens from user to vendor”);
(sent,) = msg.sender.call{value: amountOfNativeCurrencyToTransfer}(“”);
tokensPerNativeCurrency = tokensPerNativeCurrency + 1;
require(sent, “Failed to send NativeCurrency to the user”);
}
function getNumberOfTokensInNativeCurrency() public view returns(uint256) {
return tokensPerNativeCurrency;
}
function withdraw() public onlyOwner {
uint256 ownerBalance = address(this).balance;
require(ownerBalance > 0, “No NativeCurrency present in Vendor”);
(bool sent,) = msg.sender.call{value: address(this).balance}(“”);
require(sent, “Failed to withdraw”);
}
}
Dit