Вы здесь

Как создать токен по стандарту ERC20 простым способом

Цель этой статьи – показать как создаются токены по стандарту ERC20 за максимально короткий срок.

Как создать токен по стандарту ERC20 простым способом

Давайте начнем с азов: Что такое токен ERC20?

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

Что делает токены ERC20 такими привлекательными и успешными? Есть несколько факторов:

  1. Как станет понятно из этого обучающего пособия, токены ERC20 легки и просты в развертывании.
  2. Стандарт ERC20 решает существенную проблему, так как рынкам на основе блокчейна и крипто-кошелькам нужен единый, стандартизированный набор команд для связи с токенами, которыми они управляют. Это включает в себя правила взаимодействия между различными токенами, а также правила покупки токенов.
  3. Это была первая популярная Спецификация, предлагающая стандартизацию токенов Эфириума. Она ни коим образом не была первой, но благодаря своей популярности быстро стала отраслевым стандартом.

Как и другие токены Эфириума, токены ERC20 реализуются в виде умных контрактов и выполняются на виртуальной машине Эфириума (EVM) децентрализованным образом.

Solidity: язык программирования умных контрактов

Умные контракты Эфириума пишутся на языке программирования Solidity. Хотя существуют альтернативные языки, вряд ли кто-то будет использовать их для этой цели. Solidity подобен JavaScript, поэтому, если у вас есть некоторые знания JavaScript или даже Java и других C-подобных языков, у вас не должно возникнуть сложностей в понимании, что делает фрагмент кода на языке Solidity, даже до того, как вы реально освоите Solidity в достаточной мере, чтобы пользоваться им.

Вот здесь и начинается самое интересное, так как вы должны быть в состоянии начать создавать простой контракт ERC20 в кратчайшие сроки. Это конкретная и достаточно простая задача: в этой статье будет показано, как вы можете написать и развернуть токен ERC20 менее чем за час.

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

Обзор стандарта ERC20

Что такое ERC20?

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

function totalSupply() public view returns (uint256); function balanceOf(address tokenOwner) public view returns (uint); function allowance(address tokenOwner, address spender) public view returns (uint); function transfer(address to, uint tokens) public returns (bool); function approve(address spender, uint tokens) public returns (bool); function transferFrom(address from, address to, uint tokens) public returns (bool);

Функции ERC20 позволяют внешнему пользователю, скажем, приложению крипто-кошелька, узнать баланс пользователя и перевести средства от одного пользователя к другому с надлежащей авторизацией.

В умном контракте определены два конкретных события (Подтверждение и Перевод):

event Approval(address indexed tokenOwner, address indexed spender, uint tokens); event Transfer(address indexed from, address indexed to, uint tokens);

Эти события будут вызваны или опубликованы, когда пользователю будут предоставлены права на получение токенов со счета и после того, как токены будут по факту переведены.

Помимо функций стандарта ERC20, многие токены ERC20 также определяют дополнительные поля, и некоторые из них стали фактической частью стандарта ERC20, если не на письме, то на практике. Ниже приведены несколько примеров таких полей.

string public constant name; string public constant symbol; uint8 public constant decimals;

Вот несколько моментов, касающихся ERC20 и номенклатуры Solidity:

  • Доступ к открытой функции (public function) может быть за пределами самого контракта;
  • Вид (view) в основном означает константу, т. е. внутреннее состояние контракта не будет изменяться функцией;
  • Событие (event) – это способ Solidity, позволяющий клиентам, например, внешнему интерфейсу вашего приложения быть уведомленным о конкретных явлениях в рамках контракта.

Большинство конструкций языка Solidity не должны вызывать проблем с пониманием, если вы уже обладаете необходимыми навыками Java/JavaScript.

Написание токена ERC20 на языке Solidity

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

Во-первых, нам нужно определить два объекта проекции. Это понятие Solidity для ассоциативного ряда, или другими словами ряда «ключ/значение».

mapping(address => uint256) balances; mapping(address => mapping (address => uint256)) allowed;

Выражение проекции (address => uint256) определяет ассоциативный ряд, ключи которого относятся к типу address – число, используемое для обозначения учетной записи адреса и чьи значения относятся к типу uint256 — 256-битное целое число, как правило, используется для хранения остатка токенов.

Первый объект проекции, balances, будет содержать информацию об остатке токенов каждого владельца счета.

Второй объект проекции, allowed, будет включать в себя все счета, которым разрешено выйти из данной учетной записи вместе с выводом суммы для каждого.

Как вы видите, область value проекции allowed само по себе является проекцией адреса счета привязки к утвержденной для него сумме вывода средств.

Эти проекции наряду со всеми другими полями контракта будут храниться на блокчейне и будут майниться, приводя в результате к изменениям, которые будут распространяться на всех пользователей сети (узлы).

Хранение на блокчейне – дорогое удовольствие, и пользователям вашего контракта так или иначе придется платить. Поэтому всегда нужно стараться минимизировать размер хранилища и записывать в блокчейн.

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

Определение количества токенов для ICO

Как определить количество токенов для первичного размещения монет? Ну, есть несколько способов установить максимальное количество токенов для ICO, и этот вопрос сам по себе заслуживает длительного обсуждения.

В контексте нашего пособия по ECR20 мы будем использовать самый простой подход: установить общее количество токенов на момент создания контракта и изначально присвоить их "владельцу контракта", т. е. учетной записи, которая развернула умный контракт:

uint256 totalSupply_; constructor(uint256 total) public { totalSupply_ = total; balances[msg.sender] = _totalSupply; }

Конструктор (Constructor) – это специальная функция, автоматически вызываемая Эфириумом сразу после развертывания контракта. Обычно она используется для инициализации состояния токена с помощью параметров, переданных учетной записью, развертывающей контракт.

msg является глобальной переменной, объявляемой и заполняемой самим Эфириумом. Она содержит важные данные для выполнения контракта. Поле, которое мы используем здесь: msg.sender содержит данные об учетной записи Эфириума, выполняющей функцию текущего контракта.

Только учетная запись, развертывающая контракт, может вводить конструктор контракта. При запуске контракта эта функция выделяет доступные токены на счет "владелец контракта".

Получить общее количество токенов

function totalSupply() public view returns (uint256) { return totalSupply_; }

Эта функция возвращает количество всех токенов, выделенных по этому контракту, независимо от владельца.

Получить остаток токенов со счета владельца

function balanceOf(address tokenOwner) public view returns (uint) { return balances[tokenOwner]; }

balanceOf вернет текущий остаток токенов со счета, идентифицированного по адресу его владельца.

Перевести токены на другой счет

function transfer(address receiver, uint numTokens) public returns (bool) { require(numTokens <= balances[msg.sender]); balances[msg.sender] = balances[msg.sender] — numTokens; balances[receiver] = balances[receiver] + numTokens; emit Transfer(msg.sender, receiver, numTokens); return true; }

Как следует из названия, функция transfer (перевод) используется для перемещения суммы токенов со счета одного владельца на счет другого владельца, или получателя. Тот владелец счета, который осуществляет перевод, обозначается как msg.sender, т.е. это то лицо, которое выполняет функцию, что подразумевает, что только владелец токенов может переводить средства другим участникам.

Способ утверждения предиката на языке Solidity – это require (требовать). В этом случае это означает, что на передающем счете имеется достаточный баланс для осуществления перевода. Если не получается выполнить require, транзакция автоматически сворачивается без внесения изменений в блокчейн.

Прямо перед выходом функция инициирует событие ERC20 «Transfer» (перевод), тем самым позволяя зарегистрированным слушателям среагировать на его завершение.

Утвердить делегата для списывания токенов

Эта функция чаще всего используется в сценарии рынка токенов.

function approve(address delegate, uint numTokens) public returns (bool) { allowed[msg.sender][delegate] = numTokens; emit Approval(msg.sender, delegate, numTokens); return true; }

Задача approve (утвердить) – это позволить владельцу, т. е. msg.sender, утвердить счет делегата — возможно, сам рынок, — для снятия токенов со своего счета и перевода их на другие счета.

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

В конце выполнения операции эта функция инициирует событие Approval (подтверждение).

Получить количество токенов, подтвержденных для снятия со счета

function allowance(address owner, address delegate) public view returns (uint) { return allowed[owner][delegate]; }

Эта функция возвращает подтвержденное на текущий момент владельцем счета количество токенов для конкретного делегата, как установлено функцией approve.

Перевести токены делегатом

Функция transferFrom – это узел функции approve, о которой мы говорили ранее. Она позволяет делегату, одобренному для вывода средств, переводить средства владельца счета на сторонний счет.

function transferFrom(address owner, address buyer, uint numTokens) public returns (bool) { require(numTokens <= balances[owner]); require(numTokens <= allowed[owner][msg.sender]); balances[owner] = balances[owner] — numTokens; allowed[owner][msg.sender] = allowed[from][msg.sender] — numTokens; balances[buyer] = balances[buyer] + numTokens; Transfer(owner, buyer, numTokens); return true; }

Две команды require на момент запуска функции требуются для подтверждения того, что транзакция законна, т.е. что владелец счета имеет достаточное количество токенов для перевода и что делегат имеет разрешение на снятие (как минимум) numTokens.

Помимо перевода суммы numTokens от владельца к покупателю, эта функция также вычитает numTokens с денежного пособия делегата. Это в основном позволяет делегату, учитывая сумму приведенного денежного пособия, разбивать его на несколько отдельных сумм для снятия, что характерно для рынка.

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

Библиотека языка Solidity – SafeMath

SafeMath - это библиотека языка Solidity, задача которой – борьба с хакерами, которые, как известно, нарушают целостность контрактов, т.е. провоцируют целочисленное переполнение. При такой атаке хакер заставляет контракт использовать неправильные числовые значения.

SafeMath защищает от этого путем проверки на переполнение перед выполнением арифметических действий, таким образом устраняя опасность. Библиотека настолько мала, что влияние на размер контракта минимально, она не требует большой производительности и больших затрат на хранение.

Добавим SafeMath к нашему коду:

library SafeMath { // Only relevant functions function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a — b; } function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; assert(c >= a); return c; } }

SafeMath использует команды подтверждения отсутствия ошибок для проверки правильности передаваемых параметров. Если не удается подтвердить отсутствие ошибок, выполнение функции будет немедленно приостановлено и все изменения в блокчейне будут отменены.

Далее добавим следующую команду, которая помещает библиотеку в компилятор Solidity:

using SafeMath for uint256;

Затем заменим простую арифметику, которую мы использовали в начале, на функции SafeMath:

balances[msg.sender] = balances[msg.sender].sub(numTokens); balances[receiver] = balances[receiver].add(numTokens); balances[buyer] = balances[buyer].add(numTokens); balances[owner] = balances[owner].sub(numTokens);

Все пакуем вместе

На языке Solidity функции и события умного контракта собраны в единство, называемое контрактом, который можно тихо перевести в «класс блокчейна». Ниже приведен совместимый с ERC20 контракт, который мы создали, включая Gist нашего кода. Поля «название» и «символ» могут быть изменены по желанию. Большинство токенов сохраняют десятичное значение в 18, поэтому мы сделаем то же самое.

Развертывание контракта на Эфириуме

Пришло время развернуть наш контракт на блокчейне. После развертывания наш контракт будет разослан на все узлы (ноды), которые участвуют в сети. Все изменения в контракте будут распространены между всеми участвующими узлами (нодами).

Разработчики Эфириума обычно применяют такие инструменты для развертывания, как Truffle. Но даже Truffle – это перебор для этой статьи с ограниченным набором потребностей, поэтому простого он-лайн инструмента, такого как Remix, будет достаточно.

Для его использования необходимо установить плагин MetaMask на ваш браузер и завести учетную запись на Rinkeby (тестовая сеть Эфириума) с хотя бы минимальным количеством эфира Rinkeby в ней. Это относительно простые шаги, поэтому мы не будем вдаваться в подробности.

Если у вас нет эфира, перейдите на MetaMask и Rinkeby, чтобы скачать ссылки и получить четкие инструкции по установке и использованию.

Теперь, когда все на месте, мы зайдем на Remix и вставим вышеуказанный код, включая строку pragma и библиотеку SafeMath, в онлайн-редактор.

Затем мы перейдем на вторую вкладку справа под названием Run (запуск) и кликнем на Deploy (развернуть). Появится всплывающее окно MetaMask с просьбой подтвердить транзакцию. Конечно, мы подтверждаем ее.

  • Зеленый прямоугольник: убедитесь, что вы на Rinkeby
  • Синий прямоугольник: Установите общее предложение токенов
  • Красный прямоугольник: Развернуть!

Gist: https://gist.github.com/giladHaimov/8e81dbde10c9aeff69a1d683ed6870be#file-basicerc20-sol

Поздравляю! Вы только что развернули ваш первый токен ERC20, прямо как настоящий знаток блокчейна Эфириум. Как и было обещано, токен прост и легок, однако полностью функционален, соответствует стандарту ERC20 и защищен библиотекой MathSafe. Его можно покупать, им можно расплачиваться и его можно передавать через блокчейн.

Это все, что нужно для умных контрактов?

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

Умные контракты могут быть гораздо более сложными, в зависимости от вашей бизнес-логики, моделируемого вами взаимодействия с пользователем, независимо от того, обеспечиваете ли вы «чеканку» или «проживание» токенов; а также изменений жизненного цикла, которые вы вводите в контракт, необходимости в получении возможностей на уровне администратора, которые обычно идут вместе с авторизованным администратором набором функций, и так далее. Ну вы поняли.

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

Умный контракт-это фрагмент кода, выполненный на виртуальной машине Эфириума. Умный контракт на Эфириуме является неизменным и он может отправлять или получать эфир и данные.

Проще говоря, токены ERC20-это контракты, реализующие стандарт ERC20. Операции, выполняемые по этим контрактам, включают получение общего предложения и баланса токенов, а также методы, используемые для их передачи.

Разработка Эфириума в настоящее время ведется на Solidity, контрактно-ориентированном языке программирования, вдохновленном JavaScript, Python и C++.

ERC означает запрос Эфириума на комментарии. Этому запросу присвоено число 20, отсюда и суффикс.

Категория: 
Tutorial
Монета: 
2
Ваша оценка: Нет Средняя: 2 (1 оценка)
32835 / 0
Аватар пользователя Daritas
Публикацию добавил: Daritas
Дата публикации: чт, 10/25/2018 - 09:37

Что еще почитать:

Комментарии:

Борминг

Это точно не для средних умов, создание самого простого токена erc20 для меня невыполнимая задача)

чт, 10/25/2018 - 20:00

Джером

Думаю, если кому-то понадобится создать токен ERC-20, то простой способ не подойдёт, обязательно должны быть умные контракты.

пт, 11/02/2018 - 00:16

Юлия

Спасибо за полезную статью! Но намного проще и быстрее можно создать токен на платформе MyWish.io, это подойдет каждому, т.к. не требует написания кода.

ср, 04/29/2020 - 14:28