Еще на пятой неделе @Web3bridge мы написали смарт-контракт, который реализует механизм ставок для указанного токена ERC20, позволяя пользователям ставить и снимать токены, получая при этом вознаграждения в зависимости от продолжительности их ставок и указанного процента вознаграждения.
Он также включает в себя функции вывода эфира и получения вознаграждений. Контракт наследуется от контракта ERC20
и соответствует стандартному интерфейсу ERC20 для взаимодействия токенов. Я объясню каждую часть кода шаг за шагом:
Идентификатор лицензии SPDX и директива Pragma:
// SPDX-License-Identifier: MIT pragma solidity 0.8.20;
В этом разделе указывается идентификатор лицензии (MIT) и используемая версия компилятора Solidity (0.8.20).
Импорт ERC20 из контрактов OpenZeppelin:
import {ERC20} from "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol";
Контракт импортирует контракт ERC20
из библиотеки контрактов OpenZeppelin. Этот импортированный контракт используется в качестве основы для создания собственного токена ERC20.
Объявление интерфейса:
interface IStandardToken { function balanceOf(address account) external view returns (uint256); function totalSupply() external view returns (uint256); function transfer(address to, uint256 amount) external returns (bool); function transferFrom(address from, address to, uint256 amount) external returns (bool); function withdrawEther() external; }
Интерфейс IStandardToken
объявлен с функциями, определяющими стандартный интерфейс токена ERC20, включая balanceOf
, totalSupply
, transfer
, transferFrom
и withdrawEther
.
Заявление о договоре доли:
contract Stake is ERC20 { // ... }
Контракт Stake
объявлен и наследуется от контракта ERC20
. Это означает, что контракт Stake
представляет собой токен ERC20 с дополнительными функциями ставок.
Переменные состояния:
IStandardToken standardToken; struct stakeStruct { uint amountStaked; uint timeStaked; // keep track of when stake happened } uint public rewardPercent = 1; mapping(address => stakeStruct) public userStakeMap;
standardToken
: Экземпляр интерфейсаIStandardToken
, представляющий токен, который пользователи будут стейкать.stakeStruct
: пользовательская структура данных, используемая для хранения информации о ставке пользователя, включая сумму ставки и время ее размещения.rewardPercent
: общедоступная переменная, представляющая процент вознаграждений, полученных участниками. Изначально он установлен на уровне 1%.userStakeMap
: сопоставление, которое связывает адреса Ethereum с записямиstakeStruct
, позволяя контракту отслеживать долю каждого пользователя.
Конструктор:
constructor(address _standardToken) ERC20("RewardToken", "RWT") { standardToken = IStandardToken(_standardToken); }
Конструктор контракта принимает адрес стандартного токена ERC20 в качестве аргумента и инициализирует переменную standardToken
. Он также инициализирует токен ERC20
с именем «RewardToken» и символом «RWT».
События:
event Staked(uint amountstake, uint totalAmountStaked, uint time); event unStaked(uint amountstake, uint totalAmountStaked, uint time, uint rewards); event claimReward(uint time, uint rewards);
Объявлено, что эти события регистрируют важные действия по контракту, такие как ставка, отмена ставки и получение вознаграждения. Они полезны для мониторинга активности контрактов.
Функция ставок:
function stake(uint _amount) external { // ... }
Эта функция позволяет пользователям ставить определенное количество токенов. Он проверяет баланс токенов пользователя, переносит токены в контракт и записывает детали ставки в userStakeMap
.
Функция снятия ставок:
function unStake(uint _amount) external { // ... }
Пользователи могут использовать эту функцию для снятия определенного количества токенов. Он проверяет баланс пользователя, передает токены обратно пользователю, а также рассчитывает и выдает вознаграждения, если это применимо.
Функция вывода эфира:
function withdrawEther() external { standardToken.withdrawEther(); payable(msg.sender).transfer(address(this).balance); }
Эта функция вычисляет вознаграждения, на которые имеет право стейкер, на основе продолжительности ставки и процента вознаграждения.
Функция расчета вознаграждения:
function calculateRewards(address _staker) public view returns (uint) { // ... }
Эта функция вычисляет вознаграждения, на которые имеет право стейкер, на основе продолжительности ставки и процента вознаграждения.
Функция получения вознаграждений:
function claimRewards() public { // ... }
Стейкеры могут использовать эту функцию, чтобы получить свои награды. Он рассчитывает и выдает вознаграждения, обновляет временную метку ставок и генерирует событие claimReward
.
Функции возврата и получения:
fallback() external payable {} receive() external payable {}
Эти функции позволяют контракту получать эфир. Функция fallback
вызывается, когда контракт получает эфир без специального вызова функции, а функция receive
вызывается, когда контракт получает эфир посредством прямого платежа.