Что такое токены стандарта ERC20?

Что такое токены стандарта ERC20?

5
(1)

Стандарт ERC20

Стандарт ERC20 — это минимальный набор функций и переменных, которые должны быть в коде токена. Вы можете создать не соответствующий стандарту ERC20 токен и он будет прекрасно работать, однако биржи откажутся принимать такой токен, а также возникнут проблемы с правильным отображением вашего токена в Ethereum-кошельках. В этой статье разберем по косточкам все составляющие этого стандарта.

Итак, что должен содержать в себе токен стандарта ERC20:

  • публичную переменную (или константу) name с именем токена;
  • публичную переменную (или константу) symbol с 3-4 буквенным кодом токена;
  • публичную переменную (или константу) totalSupply, содержащую в себе общее количество выпущенных токенов;
  • публичный мэппинг balanceOf, содержащий в себе балансы пользователей в виде адрес=>количество;
  • событие Transfer, запускающееся в случае успешного выполнения функции transfer;
  • функция transfer, позволяющая переводить токены с адреса на адрес;
  • функцию approve, позволяющая делегировать токены;
  • событие Approval, запускающееся в случае делегирования токенов;
  • функцию transferFrom, позволяющая переводить делегированные токены;
  • мэппинг allowance, хранящий в себе адреса и кол-во делегированных токенов.

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

function name() view returns (string name){
        returns imya;
        }

Также подобную функцию стоит применять в тех случаях, если согласно логике вашего смарт-контракта переменная приватная, а не публичная.

Токен может содержать в себе более богатый функционал, но если вы делаете токен стандарта ERC20 все вышеперечисленные пункты должны в нем содержаться.

Последние 4 пункта (approve + Approval + transferFrom + allowance) могут ввести новичков в ступор, но обо всем по-порядку.

Более подробно о модификаторах видимости (публичные, приватные) я расскажу в следующих уроках.

Код стандарта ERC20

Давайте рассмотрим код токена стандарта ERC20.

pragma solidity ^0.4.23;

contract SimpleERC20Token {

    mapping (address => uint256) public balanceOf;

    string public name = "Simple ERC20 Token";
    string public symbol = "SET";
    uint8 public decimals = 18;

    uint256 public totalSupply = 1000000 * (uint256(10) ** decimals);

    event Transfer(address indexed from, address indexed to, uint256 value);

    constructor() public {

        balanceOf[msg.sender] = totalSupply;
        emit Transfer(address(0), msg.sender, totalSupply);
    }

    function transfer(address to, uint256 value) public returns (bool success) {
        require(balanceOf[msg.sender] >= value);

        balanceOf[msg.sender] -= value;
        balanceOf[to] += value;
        emit Transfer(msg.sender, to, value);
        return true;
    }

    event Approval(address indexed owner, address indexed spender, uint256 value);

    mapping(address => mapping(address => uint256)) public allowance;

    function approve(address spender, uint256 value)
        public
        returns (bool success)
    {
        allowance[msg.sender][spender] = value;
        emit Approval(msg.sender, spender, value);
        return true;
    }

    function transferFrom(address from, address to, uint256 value)
        public
        returns (bool success)
    {
        require(value <= balanceOf[from]);
        require(value <= allowance[from][msg.sender]);

        balanceOf[from] -= value;
        balanceOf[to] += value;
        allowance[from][msg.sender] -= value;
        emit Transfer(from, to, value);
        return true;
    }
}

В первой строке видим объявление версии Солидити, на которой написан контракт.

В 3 строке объявляется контракт (класс) SimpleERC20Token. Контрактов (классов) в смарт-контракте может быть несколько, они могут наследоваться и подключаться из других файлов.

balanceOf

В 6 строке объявляется мэппинг balanceOf. Мэппинг подобен массивам, но со своими особенностями, их рассмотрим в других уроках. Мэппинг хранит в себе значения в виде ключ=>значение , в нашем случае он хранит адрес=>кол-во токенов, то есть всех владельцев токена. Если владельцев 10, то будет 10 записей, если 100 000, то соответственно 100 000.

Name, Symbol

В строках 8, 9 объявляются публичные переменные name и symbol, содержащие в себе имя токена и краткий символ соответственно. Для публичной переменной (как и для публичного мэппига) автоматически создается геттер-функция для просмотра значения, то есть нам не надо писать отдельной функции для просмотра значения типа:

function name() view returns (string name){
 return name;
}

Солидити автоматически создает такие функции для публичных переменных.

decimals

Солидити не умеет работать с плавающей запятой, поэтому используется указание кол-во знаков после запятой. 18 — наиболее популярное значение, потому что и сам эфир состоит из 10 в степени 18 вей (1ETH = 1000000000000000000 вей). Значит «мельчайшей копейкой» нашего токена будет 0,000000000000000001. Можно указать decimals=2, тогда «мельчайшей копейкой» станет 0,02.
decimals необязательно должна присутствовать в коде. Без нее токен не будет содержать чисел после запятой, это значит что отправлять можно будет только целое число токенов без «копеек».
Хоть decimals и не обязательна, но если вы ее используете, то называться она должна именно decimals и никак иначе.

totalSupply

В переменной totalSupply хранится общее кол-во выпущенных токенов. Эта переменная обязательно должна присутствовать в контракте.

Событие Transfer

Событие Transfer, как можно догадаться из названия, информирует блокэксплореры, web3 интерфейсы и кошельки о том, что выполнилась функция transfer. И запускается оно в функции transfer. Это событие должно быть обязательно в контракте.

Конструктор

Констуктор выполняется 1 раз в момент деплоя контракта в блокчейн. Начиная с версии Солидити 0.4.22 изменился способ записи конструктора. Если раньше это была функция с именем контракта:

function SimpleERC20Token() public { 
  balanceOf[msg.sender] = totalSupply; 
  emit Transfer(address(0), msg.sender, totalSupply); 
}

теперь конструктор записывается словом constructor:



constructor() public {
  balanceOf[msg.sender] = totalSupply;
  emit Transfer(address(0), msg.sender, totalSupply);
}

Конструктор перечисляет все созданные токены создателю токена и запускает событие transfer. Ссобытие можно и не размещать в конструкторе, просто считается хорошим тоном его там иметь, так как токены переводятся на баланс создателя пусть и без использования функции transfer.

transfer

С помощью функции transfer владелец токенов может отправить их на другой ETH-адрес. Функция требует адрес отправителя и кол-во токенов и после выполнения возвращает булево значение (true в случае успеха и false в случае неуспеха).

  • require(balanceOf[msg.sender] >= value); проверяет что на балансе отправителя больше или равно отправляемому значению, чтобы не отправил больше чем есть.
    В случае неуспеха прекратит работу функции и вернет false, комиссия (газ) за транзакцию не спишется;
  • balanceOf[msg.sender] -= value; строка эквивалентрна записи balanceOf[msg.sender] = balanceOf[msg.sender] — value; Вычитаем из баланса отправителя количество отправляемых токенов;
  • balanceOf[to] += value; — эквивалентно записи balanceOf[to] = balanceOf[to] + value; Прибавляем кол-во токенов на баланс получателя;
  • emit Transfer(msg.sender, to, value); — запускает событие Transfer с адресом отправителя, адресом получателя и количеством отправленных токенов;
  • return true; — возвратит true.

Делегирование токенов

Делегирование токенов осуществляется с помощью approve + Approval + transferFrom + allowance.

Представьте, что у Боба есть 10 000 токенов. Боб может позволить (делегировать) Алисе распоряжаться 500 своих токенов.

Боб идет на сайт Myetherwallet  и запускает функцию approve, записывая в соответствующие строки адрес Алисы и количество токенов.

Делегирование токенов

Функция approve записывает адрес Боба, адрес Алисы и кол-во токенов в мэппинг allowance. Можем посмотреть это запустив мэппинг:

Теперь Алиса может перейти в MyEtherWallet и в любой момент перевести эти 500 (точнее меньше или равно 500) токенов себе или кому-либо еще с помощью функции transferFrom, вставив в соответствующие поле _from adress адрес Боба, в поле _to address любой адрес, включая свой, в поле _value количество токенов.


Пока Алиса не перевела токены (не запустила transferFrom) Боб может зайти в MyEtherWallet и обломать Алисе кайф обнулить количество делегированных токенов.

Зачем все это нужно?

Представьте биржу типа Эфердельты. У вас есть 5000 токенов и вы хотите их продать. Вы заходите на биржу и выставляете в стакан заявку на продажу ваших 5000 токенов за 2 ETH. Биржа с помощью Метамаска проверяет что токены принадлежат вам, потом обращается к смарт-контракту ваших токенов и запускает функцию approve, позволяющей ей распорядится вашими 5000 токенами. Через несколько минут в стакане находится покупатель ваших токенов, и тогда биржа переводит с помощью transferFrom ваши 5000 токенов на адрес покупателя, а вам взамен присылает 2 ETH с адреса покупателя. Обмен завершен, все довольны.

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 5 / 5. Количество оценок: 1

Оценок пока нет. Поставьте оценку первым.

Так как вы нашли эту публикацию полезной...

Подписывайтесь на нас в соцсетях!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

https://aurus-diploms.com/geography/kupit-diplom-rostov-na-donu.html купить диплом колледжа https://diplomy-grup24.com/kupit-diplom-v-gorode/omsk.html https://premialnie-diplom24.com/купить-диплом-омск/ https://ru-diplomirovans.com/купить-диплом-омск https://lands-diplomix.com/goroda/orenburg.html https://frees-diplom.com/kupit-attestat/attestat-9-klassov купить свидетельство о рождении https://russiany-diplomans.com/kupit-diplom-sankt-peterburg https://radiplomy.com/kupit-diplomy-sssr