Как создать и развернуть полноценное первоначальное предложение монет за один час

1656552976 kak sozdat i razvernut polnoczennoe pervonachalnoe predlozhenie monet za odin

Гилад Хаимов

1*PJSmiZfuvOPUT58q-9kRyQ

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

За последние несколько лет спецификация токенов ERC20 практически стала стандартом для токенов Ethereum. На самом деле большинство токенов Ethereum совместимы с ERC20.

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

  1. Это просто. Действительно просто. Как мы скоро узнаем.
  2. Это решает реальную проблему: блокчейн-маркетплейсы и крипто-кошельки нуждаются в едином наборе команд для связи со всеми управляемыми токенами, включая правила взаимодействия между токенами и правилами покупки токенов.
  3. Это была первая (ну почти первая) спецификация, предложившая стандартизацию токенов Ethereum.

Как и любой другой токен Ethereum, токены ERC-20 реализуются как смарт-контракты и производятся на виртуальной машине Ethereum (EVM) децентрализованным способом.

Смарт-контракты Ethereum написаны на языке Solidity (есть и другие варианты, но вряд ли кто-то ими пользуется). Solidity несколько похож на JavaScript. В самом деле, если вы немного знаете JavaScript, Java или другие языки, подобные C, вы, вероятно, поймете, что делает фрагмент кода Solidity, еще до изучения языка.

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

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

Стандарт

1*Pn9Fl-H1fuYdnXLsp5WJ6A

Что это за 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);

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

Кроме того, контракт определяет два события:

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

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

Многие маркеры также добавляют такие поля, которые фактически стали частью стандарта:

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

Относительно номенклатуры:

  • А public Доступ к функции можно получить вне самого контракта
  • view в основном означает константу, то есть внутреннее состояние контракта не будет изменено функцией
  • An event это способ Solidity, позволяющий клиентам, например, интерфейса вашей программы, получать уведомления о конкретных событиях в контракте

Остальные языковые конструкции должны быть понятны, если вы когда-либо изучали Java/JavaScript.

Код

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

Для этого нам нужно будет определить два объекта отображения, являющиеся понятием Solidity для ассоциативного или массива ключ/значения:

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

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

Первый объект отображенияt, balances, сохраняет баланс маркеров каждой учетной записи владельца.

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

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

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

Блокчейн-хранилище стоит дорого. Это стоит газ, за ​​который пользователи вашего контракта должны будут платить. Где возможно всегда старайтесь минимизировать как объем памяти, так и записи в блокчейн.

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

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

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

Для наших потребностей мы будем использовать самый простой подход, который заключается в том, чтобы установить общее количество токенов на момент создания контракта и сначала назначить их всем аккаунту «владельца контракта», то есть аккаунту, развернувшему контракт:

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

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

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

Поскольку только аккаунт развертывания может когда-либо вводить конструктор контракта, эта функция при запуске контракта выделяет все доступные маркеры для аккаунта «владельца контракта».

Получите общее количество маркеров

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

The transfer функция выполняет то, что следует из ее названия, то есть перемещает numTokens количество жетонов с баланса владельца на баланс другого пользователя receiver. Обратите внимание, что передающим владельцем является msg.sender то есть выполняющий функцию, что означает, что только владелец токенов может передавать их другим.

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

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

Разрешить делегату извлекать токены из моей учетной записи

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

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

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

Получите количество токенов, одобренных для извлечения

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

Эта функция возвращает текущее утвержденное владельцем количество маркеров определенному делегату, как это установлено в 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;}

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

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

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

Если на самом деле мы могли бы остановиться на этом и иметь действительную реализацию ERC20. Но мы стремимся выше: мы хотим промышленный токен крепости, хотя и простой. Это требует от нас сделать наш код немного безопаснее.

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

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 использует assert операторы для проверки правильности передаваемых параметров. Когда assert не удается, выполнение функции немедленно прекращается, а все изменения в блокчейне откатываются.

Далее давайте добавим такой оператор, представляющий библиотеку компилятора 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 функции и события контракта завернуты в сущность, которая называется a контракт который вы можете молча перевести на «класс блокчейна». Ниже приведен контракт, совместимый с ERC20, который мы создали. По желанию можно изменять поля имени и символов. Большинство токенов сохраняют десятичное значение 18. Мы сделаем то же самое здесь:

Развертывание контракта

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

Профессионалы Ethereum обычно работают с такими инструментами развертывания, как Truffle.
Для наших нужд будет достаточно простого онлайн-инструмента под названием Remix.

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

Если у вас нет ни одного из них, смело посетите MetaMask и Rinkeby
для получения четких инструкций по установке и использованию.

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

После этого мы перейдем ко 2-й вкладке ‘бежать на правой панели и нажмите «развернуть». Появится всплывающее окно MetaMask с просьбой подтвердить транзакцию, что мы, конечно, будем.

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

Поздравляю! Вы только что развернули свой первый токен ERC20. Он прост, но полностью функционален, отвечает стандартам, безопасен и готов к покупке, оплате и передаче по всей сети Blockchain!

Это все?

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

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

Надеюсь, это тоже было немного весело.

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

Ваш адрес email не будет опубликован.