как найти адрес контракта токена
inaword
Блог о разработке и современных технологиях
Пишем смарт-контракт Ethereum — это просто: Часть 7 — ICO
В сегодняшнем уроке вы узнаете как быстро создать смарт-контракт ico на ethereum. Конечно быстрый подход не лучший вариант когда вы работаете с деньгами. Но в учебных целях подойдет. Наш первый пример контракта ico на Solidity для Ethereum будет очень простым. А впоследствии мы будем его дополнять полезными фичами. Итак, приступим.
ICO — Initial Coin Offering. Первичное предложение токенов. Если вы вообще не знакомы с этим понятием, то сперва загляните на википедию. Вкратце на примере.
Допустим у группы людей появилась идея, но на ее реализацию нужны деньги. Тогда они рекламируют свою идею и призывают вложиться. Взамен они дают токены — валюту своего проекта. И как правило владельцам этих токенов что-то обещают. Например разделить между владельцами токенов какую-то часть прибыли проекта.
Жизненный цикл ICO может состоять из следующих стадий:
Мы сосредоточимся на второй части. Технически процесс прост. Инвестор отправляет эфир на контракт, отвечающий за распродажу. А контракт распродажи отдает команду выпустить токены и зачислить на ваш баланс.
Итак ICO состоит из двух контрактов:
В предыдущем уроке мы уже реализовали свой токен ERC20. И он был создан с применением шаблонам MintableToken. Т.е. он уже содержит функцию, которая выпускает новые токены на адрес владельца. Нам осталось только написать контракт распродажи!
Давайте условимся что распродажа токенов будет начинаться 18 июля 2017 года в 15 часов по Москве и длиться будет 30 дней. В solidity дата представляется в UNIX формате. Это количество секунд с 1 января 1970 года (можно воспользоваться сервисом перевода тут). При этом время должно быть указано не местное, а относительно Гринвичевского меридиана GMT. Итак разница между Москвой и GMT у нас + 3 часа. Тогда время начал распродажи по GMT — 18 июля 2017 года 12.00. Теперь воспользуемся сервисом перевода в UNIX формат и получим — 1500379200. Эта дата актуальна момент написания статьи. Поскольку дальше мы будем тестировать наш контракт, то лучше указать дату вчерашнего дня.
Итак в нашем контракте Сrowdsale буду следующие переменные
Когда пользователь нам пришлет деньги мы проверим что текущая дата больше чем дата начала распродажи и меньше чем дата конца распродажи. Если так, то эфир, который нам прислал пользователь мы мы переведем на счет владельца контракта. А затем выполним выпуск токенов на счет пользователя посредством вызова mint. Давайте запишем условие проверки:
Как определить адрес смарт-контракта до деплоя: использование CREATE2 для криптобиржи
Тема блокчейна не перестает быть источником не только всяческого хайпа, но и весьма ценных с технологической точки зрения идей. Посему не обошла она стороной и жителей солнечного города. Присматриваются люди, изучают, пытаются переложить свою экспертизу в традиционном инфобезе на блокчейн-системы. Пока что точечно: одна из разработок «Ростелеком-Солар» умеет проверять безопасность софта на базе блокчейна. А попутно возникают некоторые мысли по решению прикладных задач блокчейн-сообщества. Одним из таких лайфхаков – как определить адрес смарт-контракта до деплоя с помощью CREATE2 – сегодня хочу с вами поделиться под катом.
Опкод CREATE2 был добавлен в хард-форке Константинополь 28 февраля этого года. Как указано в EIP, этот опкод был введен в основном для каналов состояний (state channels). Однако, мы использовали его для решения другой проблемы.
На бирже есть пользователи с балансами. Каждому пользователю мы должны предоставить Ethereum-адрес, на который она или он сможет отправлять токены, тем самым пополняя свой аккаунт. Давайте назовем эти адреса «кошельками». Когда токены приходят на кошельки, мы должны отправить их на единый кошелек (hotwallet).
В следующих разделах я анализирую варианты решения этой задачи без CREATE2 и рассказываю, почему мы отказались от них. Если вам интересен только конечный результат, вы можете найти его в разделе «Итоговое решение».
Ethereum-адреса
Самое простое решение — генерировать новые ethereum-адреса для новых пользователей. Эти адреса и будут кошельками. Чтобы перевести токены из кошелька в hotwallet, необходимо подписать транзакцию вызовом функции transfer() с приватным ключом кошелька из бэкенда.
Создавать отдельный смарт-контракт для каждого пользователя
Развертывание отдельного смарт-контракта для каждого пользователя позволяет не хранить приватные ключи от кошельков на сервере. Биржа вызовет этот умный контракт для передачи токенов в hotwallet.
От этого решения мы тоже отказались, поскольку пользователю нельзя показать адрес его кошелька без развертывания смарт-контракта (это на самом деле возможно, но довольно сложным образом с другими недостатками, которые мы не будем здесь обсуждать). На бирже пользователь может создать столько аккаунтов, сколько ему нужно, и каждому нужен собственный кошелек. Это означает, что нам нужно тратить деньги на деплой контракта, даже не будучи уверенными, что пользователь будет использовать эту учетную запись.
Опкод CREATE2
Чтобы устранить проблему предыдущего способа, мы решили использовать опкод CREATE2. CREATE2 позволяет заранее определить адрес, по которому будет развернут смарт-контракт. Адрес рассчитывается по следующей формуле:
keccak256 (0xff ++ address ++ salt ++ keccak256 (init_code)) [12:]
Больше улучшений
Предыдущее решение все еще имеет один недостаток: вам нужно платить за развертывание умного контракта. Тем не менее, вы можете избавиться от этого. Для этого вы можете вызвать функцию transfer(), а затем selfdestruct() в конструкторе кошелька. И тогда газ за развертывание смарт-контракта будет возвращен.
Вопреки распространенному заблуждению, вы можете развернуть смарт-контракт по одному и тому же адресу несколько раз с опкодом CREATE2. Это связано с тем, что CREATE2 проверяет, что nonce целевого адреса равен нулю (ему присваивается значение «1» в начале конструктора). При этом функция selfdestruct() каждый раз сбрасывает nonce адреса. Таким образом, если вы снова вызовете CREATE2 с теми же аргументами, проверка на nonce пройдет.
Обратите внимание, что это решение аналогично варианту с ethereum-адресами, но без необходимости хранить приватные ключи. Стоимость перевода денег с кошелька на hotwallet примерно равна стоимости вызова функции transfer(), поскольку мы не платим за развертывание смарт-контракта.
Итоговое решение
Для каждого нового пользователя мы показываем его / ее адрес кошелька путем расчета
keccak256 (0xff ++ address ++ salt ++ keccak256 (init_code)) [12:]
Когда пользователь переводит токены на соответствующий адрес кошелька, наш бэкэнд видит событие Transfer с параметром _to, равным адресу кошелька. На этот момент уже возможно увеличить баланс пользователя на бирже до развертывания кошелька.
Когда на адресе кошелька накапливается достаточное количество токенов, мы можем перевести их все сразу в hotwallet. Для этого бекенд вызывает функцию фабрики смарт-контрактов, которая выполняет следующие действия:
function deployWallet (соль uint256) <
bytes memory walletBytecode =…;
// invoke CREATE2 with wallet bytecode and salt
>
Таким образом, вызывается конструктор смарт-контракта кошелька, который передает все свои токены на адрес hotwallet и затем самоуничтожается.
Автор Павел Кондратенков, специалист в области Ethereum
Как добавить кастомный токен в MEW web
3 минут на чтение
Любой токен ERC20 можно добавить в локальный интерфейс MEW, следуя этим инструкциям.
Убедитесь, что он уже не установлен в постоянном списке токенов
Сначала вы должны убедиться, что вашего токена нет в нашем интерфейсе по умолчанию.
Шаг 2. Чтобы найти необходимый токен, выполните поиск по нашему списку токенов по умолчанию.
Шаг 3. Если вы не видите ваш токен, продолжайте следовать инструкциям в данной статье.
Поиск информации о токене
Для добавления токена в наш интерфейс вам понадобятся три параметра: адрес контракта, число десятичных знаков и символ. Всю эту информацию можно найти с помощью проводника блокчейна Ethereum, например Etherscan.io или Ethplorer.io. Мы покажем, как ее найти через Etherscan.io.
Шаг 1. Направляйтесь на Etherscan.
Шаг 2. Если у вас есть баланс токена, который вы хотите добавить, выполните поиск вашего публичного адреса (0x…) в поисковом поле.
Шаг 3. Найдите ваш токен в выпадающем списке балансов токенов. Выберите токен, и вы попадете на экран информации о токене.
Шаг 4. Здесь вы найдете адрес контракта токена и количество десятичных знаков в правой части интерфейса. Запомните число десятичных знаков, а затем нажмите на адрес договора, чтобы перейти на главный экран токена.
Шаг 5. Скопируйте этот адрес и вернитесь на MEW. В верхней части списка токенов нажмите «+ Кастомные токены», чтобы открыть экран добавления своих токенов.
Шаг 6. Вставьте адрес контракта в верхнее поле, укажите символ токена (аббревиатуру) во втором поле и введите количество десятичных знаков в последнее поле. Затем нажмите «Сохранить». Все готово!
Распространенные проблемы
«Токен уже существует!»
Если вы увидите эту ошибку, то ее можно легко исправить. Введите информацию о своем токене еще раз, но поставьте «2» после символа. Например, если символ токена — «XYZ», то укажите «XYZ2».
Если вы все еще видите эту ошибку после сохранения токена с измененным символом, то возможно, что ваш токен уже находится в списке токенов по умолчанию. Попробуйте снова поискать его символ в списке токенов. Если он отображается с нулевым балансом, но на etherscan.io есть положительный баланс, то вам, возможно, придется поменять узел ETH в верхнем правом углу.
Мои добавленные токены исчезают!
Если токены, которые вы добавили, исчезают при каждом доступе к нашему интерфейсу, убедитесь, что у вас не установлено программное обеспечение для очистки кэша (например, CCleaner). Ваша пользовательская информация о токене хранится локально в вашем браузере, поэтому эта программа удалит эту информацию, и вам нужно будет добавлять токен при каждом доступе к кошельку.
Как определить адрес смарт-контракта до деплоя: использование CREATE2 для криптобиржи
Тема блокчейна не перестает быть источником не только всяческого хайпа, но и весьма ценных с технологической точки зрения идей. Посему не обошла она стороной и жителей солнечного города. Присматриваются люди, изучают, пытаются переложить свою экспертизу в традиционном инфобезе на блокчейн-системы. Пока что точечно: одна из разработок «Ростелеком-Солар» умеет проверять безопасность софта на базе блокчейна. А попутно возникают некоторые мысли по решению прикладных задач блокчейн-сообщества. Одним из таких лайфхаков – как определить адрес смарт-контракта до деплоя с помощью CREATE2 – сегодня хочу с вами поделиться под катом.
Опкод CREATE2 был добавлен в хард-форке Константинополь 28 февраля этого года. Как указано в EIP, этот опкод был введен в основном для каналов состояний (state channels). Однако, мы использовали его для решения другой проблемы.
На бирже есть пользователи с балансами. Каждому пользователю мы должны предоставить Ethereum-адрес, на который кто угодно сможет отправлять токены, тем самым пополняя свой аккаунт. Давайте назовем эти адреса «кошельками». Когда токены приходят на кошельки, мы должны отправить их на единый кошелек (hotwallet).
В следующих разделах я анализирую варианты решения этой задачи без CREATE2 и рассказываю, почему мы отказались от них. Если вам интересен только конечный результат, вы можете найти его в разделе «Итоговое решение».
Ethereum-адреса
Самое простое решение — генерировать новые ethereum-адреса для новых пользователей. Эти адреса и будут кошельками. Чтобы перевести токены из кошелька в hotwallet, необходимо подписать транзакцию вызовом функции transfer() с приватным ключом кошелька из бэкенда.
Этот подход имеет следующие преимущества:
Создавать отдельный смарт-контракт для каждого пользователя
Развертывание отдельного смарт-контракта для каждого пользователя позволяет не хранить приватные ключи от кошельков на сервере. Биржа вызовет этот умный контракт для передачи токенов в hotwallet.
От этого решения мы тоже отказались, поскольку пользователю нельзя показать адрес его кошелька без развертывания смарт-контракта (это на самом деле возможно, но довольно сложным образом с другими недостатками, которые мы не будем здесь обсуждать). На бирже пользователь может создать столько аккаунтов, сколько ему нужно, и каждому нужен собственный кошелек. Это означает, что нам нужно тратить деньги на деплой контракта, даже не будучи уверенными, что пользователь будет использовать эту учетную запись.
Опкод CREATE2
Чтобы устранить проблему предыдущего способа, мы решили использовать опкод CREATE2. CREATE2 позволяет заранее определить адрес, по которому будет развернут смарт-контракт. Адрес рассчитывается по следующей формуле:
Больше улучшений
Предыдущее решение все еще имеет один недостаток: вам нужно платить за развертывание умного контракта. Тем не менее, вы можете избавиться от этого. Для этого вы можете вызвать функцию transfer(), а затем selfdestruct() в конструкторе кошелька. И тогда газ за развертывание смарт-контракта будет возвращен.
Вопреки распространенному заблуждению, вы можете развернуть смарт-контракт по одному и тому же адресу несколько раз с опкодом CREATE2. Это связано с тем, что CREATE2 проверяет, что nonce целевого адреса равен нулю (ему присваивается значение «1» в начале конструктора). При этом функция selfdestruct() каждый раз сбрасывает nonce адреса. Таким образом, если вы снова вызовете CREATE2 с теми же аргументами, проверка на nonce пройдет.
Обратите внимание, что это решение аналогично варианту с ethereum-адресами, но без необходимости хранить приватные ключи. Стоимость перевода денег с кошелька на hotwallet примерно равна стоимости вызова функции transfer(), поскольку мы не платим за развертывание смарт-контракта.
Итоговое решение
Когда пользователь переводит токены на соответствующий адрес кошелька, наш бэкэнд видит событие Transfer с параметром _to, равным адресу кошелька. На этот момент уже возможно увеличить баланс пользователя на бирже до развертывания кошелька.
Когда на адресе кошелька накапливается достаточное количество токенов, мы можем перевести их все сразу в hotwallet. Для этого бекенд вызывает функцию фабрики смарт-контрактов, которая выполняет следующие действия:
Таким образом, вызывается конструктор смарт-контракта кошелька, который передает все свои токены на адрес hotwallet и затем самоуничтожается.
Полный код можно найти здесь. Обратите внимание, что это не наш продакшн-код, так как мы решили оптимизировать байт-код кошелька и записали его в опкодах.
Автор Павел Кондратенков, специалист в области Ethereum
Как написать смарт-контракт для ICO за 5 минут
В Интернетах этих ваших и так полно статьей про смарт-контракты, но как только начинаешь писать оный, сталкиваешься с тем, что информация везде повторяется, а туториалов, как запулить свой ERC20 попросту либо нет, либо они устарели что аж донельзя. К слову, чтобы эта статья оставалась актуальной, постараюсь указать потенциальные места, где она может устареть (и как это поправить). Поехали!
Solidity
Это название главного языка, который разработала команда кефира для запуска смарт-контрактов. Если вы программист, то просто пробегитесь глазами по документации языка — он неприлично простой. К слову, сделали его простым, чтобы было сложнее ошибиться в написании смарт-контракта. Так что абсолютно любой программист хотя бы уровня джуниора сможет разобраться в нем. Абсолютно нет смысла платить огромные деньги разработчикам, которые знают солидити — обучить уже существующего разработчика будет на порядок дешевле.
Смарт-контракты
А если вы пометите функцию в контракте словами Constant или View (означают одно и то же, разрешают только читать состояние), либо Pure (то же самое, только даже состояние не читает), то на исполнение этой функции даже кефир тратить не нужно будет! Даже больше скажу, эти функции не нужно вызывать транзакциями — ведь любой клиент кефира, теоретически, сможет ее выполнить у себя — и никому больше об этом знать не нужно (в блокчейн ведь ничего не пишется).
А еще есть две важные штуки в солидити: множественное наследование и модификаторы функций. Про них тоже нужно знать.
Второе — это возможности создавать функции, которые потом будут вставлены в другие функции. Это как простая инкапсуляция, только чуть более гибкая — это буквально шаблон функции. Когда вы создаете модификатор, вы пишете специальный символ _ там, где подразумеваете код функции, использующей этот модификатор. То есть модификаторы — это не просто инкапсулированный функционал, который возвращает значение; это — шаблон функции, когда код из модификатора буквально вставляется в функцию, использующую этот модификатор.
Перейдем к практике.
Готовим окружение
Если вы не знаете, что такое Терминал — почитайте вот эту статью. Если вы на окнах, ставьте себе Терминал через WLS. Если вы уже знакомы с Терминалом, продолжим. Алсо, сразу поставьте себе Node.js — он будет необходим для следующих шагов. Лучше ставить LTS, но, на самом деле, абсолютно без разницы, какую из современных версий ноды ставить.
Если вам выплюнуло версию geth — все в ажуре, продолжаем туториал. Если нет — хреново, исправляйте; придется, похоже, заняться любовными ласками с Терминалом и своей операционной системой — но вам не впервой, разберетесь. Как установите geth, запускайте в Терминале команду:
Это запустит процесс синхронизации вашей ноды с тестовым сервером, блоки которого можно глянуть вот тут. Проверить, синхронизировались ли вы с сетью в консоли geth можно, прописав:
Алсо, я накидал простенький баш-скриптик, который установит все за вас. Вызывается вот так:
— но я его ни разу не тестил еще, так что не уверен в его работоспособности. Однако пулл-реквестам буду только рад.
Фигачим контракт
За вас все уже придумано и написано — это хорошо. Немного головняка будет все равно — но я постараюсь вам его минимизировать. Использовать мы будем уже готовые ERC20 контракты от OpenZeppelin — это сейчас стандарт индустрии, они прошли аудит, да и вообще все их код используют. Спасибо им огромное за вклад в опенсоус.
Сделайте cd в какую-нибудь безопасную папку и после пропишите:
В этой папке и будем работать. Создадим здесь заглушку для нашего смарт-контракта:
Дальше нам нужно забрать текущий код смарт-контрактов из npm и, собственно говоря, начать сам проект:
Ага, вот вам и весь ERC20 интерфейс. Сложно? Не думаю. Дает возможность глянуть, сколько было выпущено токенов, проверить баланс адреса и перевести токенов на другой адрес, выплюнув в сеть событие перевода для легких клиентов кефира. И все это вы получаете фор фри в вашем MyToken.sol благодаря работе OpenZeppelin — они молодцы.
Так-так-так, что тут у нас? Что, пацаны, смарт-контракты? Наша публичная продажа токенов наследует три самых популярных свойства: у нее есть хард-кап, больше которого собрать не получится; софт-кап, не собрав который эфиры возвращаются; время начало и конца продажи токенов. Собственно говоря, а что еще для счастья нужно?
Вот и все — у вас есть готовые контракты вашего собственного ERC20 токена и даже смарт-контракт ICO, который настраивается по вашему желанию и раздает ваши токены за кефир. Алсо, его поддерживают все ERC20 кошельки — ляпота! Перейдем к ручным тестам и деплою.
Миграции
Заметка про web3.eth.accounts[0] : когда деплоите смарт-контракт, убедитесь, что geth или testrpc имеют правильный кошелек в web3.eth.accounts[0] — не теряйте приватный ключ к нему, хоть это никак вам не навредит, но вдруг владельцу что-нибудь потом нужно будет сделать, а ключа уже нет?
Тестирование и деплой
Йес, контракты готовы, миграции написаны, осталось только задеплоить и проверить. Как geth (тестовый и реальный), так и testrpc управляются одинаково через truffle console — так что опишу способ проверки для testrpc и просто расскажу, как включить geth после. И так, запускаем тестовый локальный блокчейн кефира:
Эм… вот и все. У вас локально работает симуляция блокчейна кефира.
Теперь открываем новое окошко Терминала ( testrpc не закрываем — он должен работать) и прописываем в папке проекта:
Эта магическая команда скомпилирует смарт-контракт (то есть не нужно каждый раз писать truffle compile ) и задеплоит его на микро-сервер блокчейна, найденный открытым локально. Стоит отметить, что если testrpc сделает это мгновенно, то тестовый и реальный блокчейны будут гораздо дольше включать транзакцию в следующие блоки. После этого у вас должно выплюнуться нечто подобное в консольку:
Прописываем следующее в теперь уже трюфеле (без комментариев только):
В случае с testrpc можно сразу же проверять снова баланс нашего кошелька, но в случае с тестовым и реальным блокчейном нужно подождать, пока транзакция наша будет включена в блок — обычно, когда это происходит, трюфель выдает вам номер транзакции. Подождали? Проверяем снова наш баланс в MyToken :
Заключение
Удачи в разработке смарт-контрактов! Остались вопросы? Милости прошу в комментарии — с удовольствием на все отвечу и постараюсь помочь с проблемами.
Бонус
А что, если вы хотите изменить логику, по которой считается цена покупки токенов? Конечно, можно изменить правильно rate или использовать один из классов контрактов от OpenZeppelin, но вдруг вы хотите чего-нибудь еще более извращенного? В смарт-контракте можно оверрайтнуть функцию getTokenAmount следующим образом:
В общем, так можно сделать цену токена зависящей от времени покупки — чем дальше в лес, тем дороже токены. Не бойтесь экспериментировать и переписывать некоторые функции смарт-контрактов — это весело!