Все, что нужно знать об ICO, пробуем смарт-контракт в действии
Слышали про ICO? А как насчёт выпуска собственных токенов? Разобрались, как это осуществить.
Что такое ICO
Initial Coin Offering — это новое слово в мире краудфандинга. Благодаря созданию криптовалют, по всему миру запускают стартапы и для привлечения капитала выпускают в продажу свои токены — те же акции, только для их обращения не нужны банки, сложная отчётность, время. Так вот, первоначальная продажа токенов — и есть ICO (аналог IPO).
Как это работает и откуда появилось
Сами токены основаны на системе криптовалют. А они, между прочим, разрабатываются уже более 20 лет. Да, до Bitcoin были другие попытки создать виртуальные деньги, но потребовалось время, чтобы совместить их сильные стороны.
Технология Bitcoin была описана и реализована в 2008 году, и она есть не что иное, как набор правил, по которым компьютеры обмениваются информацией обо всех сделках — блокчейн. Нет единых дата-центров, потому что одновременно с майнингом новых блоков (добычей биткоинов), пользователи обмениваются информацией, образуя распределённую базу данных.
Вот ещё большая картинка о том, как работают переводы в Bitcoin.
Сеть имеет устойчивость к атакам вроде double-spending, потому что для их проведения необходимо иметь значительный процент от суммарной мощности всей сети.
На Bitcoin дело не остановилось — появились десятки других валют, в том числе Ethereum. Он разрабатывался как усовершенствование Bitcoin: в нём добавлена поддержка «умных контрактов» и создания распределённых приложений (DApps) на Тьюринг-полных языках программирования. Именно этим и заинтересовались такие компании, как Microsoft, IBM, Сбербанк. Каждый умный контракт запускает код на компьютерах майнеров в специальной Ethereum Virtual Machine, что позволяет заключать договора, создавать ценные бумаги, не отдавая контроль какому-либо органу наподобие банка или государства — условия просто исполняются на распределённой сети.
По ссылке можно прочитать подробнее о том, как писать Dapps, на простом примере. А также ещё 3 примера на языке Solidity для вдохновения.
С точки зрения инвестирования
Вкладывая деньги на ICO, можно заработать, как и на торговле криптовалютой. Если вы инвестируете в компанию, она может и не иметь высокого дохода, но её рыночная капитализация будет оцениваться стоимостью токенов.
Как правило, условия проведения ICO — количество и цена токенов, этапы продажи — указываются заранее на сайте. Некоторые компании (в лучших традициях краудфандинга) предлагают возможность впоследствии пользоваться токенами для оплаты их товаров или услуг.
ICO в отличие от IPO:
- пока никак не регулируется государствами
- не рассчитано для выплаты дивидендов
- больше подходит для краткосрочных вложений
- покупка доступна любому
Поэтому, пока его активно применяют некоммерческие, волонтёрские организации, open-source, команды учёных.
Для тех, кого заинтересовало — ещё ссылка про инвестирование в ICO.
Как организовать ICO со своими токенами
Создать свои токены на основе существующих «умных контрактов» несложно (см. ниже). Но вообще говоря, написание документации, контракта, а после — тщательный анализ кода и тестирование — процесс очень трудоёмкий. Потому как будучи однажды выпущенным, контракт не может быть изменён.
Далее возникнут вопросы с тем, как грамотно продавать свои токены: потребуется анализ бизнеса, правовой части, пиар. Если вы действительно намерены собрать деньги посредством ICO, причём с минимумом трудозатрат, то можете обратиться к организации, оказывающей такие услуги — на сегодняшний день их уже существует множество. Вот пример: Coral, Ambisafe, Espeo
Как создавать токены и умные контракты
Если вы разобрались в том, как работает блокчейн, значит вы готовы для этого этапа и можете ознакомиться с этой системой на простых примерах своими руками. Сначала разберёмся с инструментами.
Truffle — фреймворк для создания умных контрактов и распределённых приложений;
OpenZeppelin — библиотека, содержащая отличные проверенные контракты — они все хорошо протестированы и придерживаются лучших практик по безопасности (тут не стоит изобретать велосипед, потому что небольшая ошибка может стоить очень дорого);
testrpc — быстрый и несложный Ethereum клиент (blockchain node) для тестирования и разработки;
Geth, Parity или подобный инструмент — если вы хотите создать контракт в тестовой или основной сети Ethereum.
Всё необходимое установим через npm (скачать его самого можно здесь). В терминале:
$ npm install -g ethereumjs-testrpc $ npm install -g truffle $ mkdir my-ico && cd my-ico $ truffle init $ npm install zeppelin-solidity
Теперь у вас есть всё, чтобы создавать, запускать и выпускать свои умные контракты. После этого у вас есть папка zeppelin-solidity внутри node_modules, где вы можете найти все шаблоны контрактов из библиотеки OpenZeppelin.
Мы создадим простой токен с возможностью остановки на всякий случай. А именно, мы будем иметь возможность приостановить торговлю с нашими токенами во время краудфандинга, если что-то пойдёт не так.
Первый шаг — создание контракта токена
touch contracts/ProglibCoin.sol
А в коде:
pragma solidity ^0.4.11; import 'zeppelin-solidity/contracts/token/MintableToken.sol'; contract ProglibCoin is MintableToken { string public name = "PROGLIB COIN"; string public symbol = "PRL"; uint256 public decimals = 18; }
Это — базовое решение для контрактов. Таким образом, OpenZeppelin лишает нас необходимости хардкодить. Мы обращаемся к MintableToken, чтобы обозначить, что токены управляются, эмитируются их владельцем. Подробнее можно изучить в исходном коде: node_modules/zeppelin-solidity/contracts/token/MintableToken.sol
Следующий шаг — создание Crowdsale контракта
touch contracts/ProglibCoinCrowdsale.sol
Мы собираемся унаследовать его от:
node_modules/zeppelin-solidity/contracts/crowdsale/Crowdsale.sol: pragma solidity ^0.4.11; import './ProglibCoin.sol'; import 'zeppelin-solidity/contracts/crowdsale/Crowdsale.sol'; contract ProglibCoinCrowdsale is Crowdsale { function ProglibCoinCrowdsale(uint256 _startBlock, uint256 _endBlock, uint256 _rate, address _wallet) Crowdsale(_startBlock, _endBlock, _rate, _wallet) { } // Создание токена для продажи // Перегружаем эту функцию, чтобы создавать свои MintableToken function createTokenContract() internal returns (MintableToken) { return new ProglibCoin(); }
Согласитесь, красиво? В родительский конструктор Crowdsale мы должны передать параметры startBlock, endBlock (для любопытных, один час — это примерно 212 блоков), rate (tokens per ether), а также wallet — адрес владельца контракта.
Теперь опробуем контракт в действии
В терминале:
$ testrpc -u 0
Эта команда запустит testrpc с одним разблокированным аккаунтом.
Далее откройте файл migrations/2_deploy_contracts.js и измените его следующим образом:
var ProglibCoinCrowdsale = artifacts.require("./ProglibCoinCrowdsale.sol") module.exports = function(deployer, network, accounts) { const startBlock = web3.eth.blockNumber + 2 // номер блока, с которого начнётся продажа. Пусть будет через 2 после текущего const endBlock = startBlock + 300 // номер блока, на котором оно завершится. 300 — это немного больше часа const rate = new web3.BigNumber(1000) // стоимость по отношению к ether в wei const wallet = web3.eth.accounts[0] // адрес — держатель счёта. Для безопасности рекомендуется использовать multisig deployer.deploy(ProglibCoinCrowdsale, startBlock, endBlock, rate, wallet) }
Обратите внимание, что мы не развёртываем ProglibCoin, потому что ProglibCoinCrowdsale и так его создаёт. Возвращаемся в терминал:
$ truffle compile $ truffle migrate
Если вы наблюдаете вкладку testrpc, то увидите, что контракт был успешно выпущен.
Итак, давайте попробуем приобрести немного PRL токенов
$ truffle console
Должна открыться консоль Truffle, где мы будем использовать API web3.js для взаимодействия с выпущенным контрактом.
// Аккаунт, приобретающий токены PRL > account1 = web3.eth.accounts[1] '0xddac5d057c79facd674bc95dfd9104076fd34d6b' // Присваивание переменной crowdsale результата функции ProglibCoinCrowdsale.deployed() - адрес экземпляра токена PRL > ProglibCoinCrowdsale.deployed().then(inst => { crowdsale = inst }) > undefined > crowdsale.token().then(addr => { tokenAddress = addr } ) > tokenAddress '0x87a784686ef69304ac0cb1fcb845e03c82f4ce16' > proglibCoinInstance = ProglibCoin.at(tokenAddress) // Далее убедимся, что account1 имеет нулевое количество PRL. proglibCoinInstance.balanceOf(account1).then(balance => balance.toString(10)) '0' // Покупка токенов PRL > ProglibCoinCrowdsale.deployed().then(inst => inst.sendTransaction({ from: account1, value: web3.toWei(5, "ether")})) { tx: '0x68aa48e1f0d0248835378caa1e5b2051be35a5ff1ded82878683e6072c0a0cfc', receipt: { transactionHash: '0x68aa48e1f0d0248835378caa1e5b2051be35a5ff1ded82878683e6072c0a0cfc', transactionIndex: 0, blockHash: '0xb48ceed99cf6ddd4f081a99474113c4c16ecf61f76625a6559f1686698ee7d57', blockNumber: 5, gasUsed: 68738, cumulativeGasUsed: 68738, contractAddress: null, logs: [] }, logs: [] } undefined // Снова проверим баланс account1. > proglibCoinInstance.balanceOf(account1).then(balance => account1PrlTokenBalance = balance.toString(10)) '5000000000000000000000' // При создании токена, мы сделали их число 18-разрядным — столько же, сколько и у ether. Выведем только значимую часть: > web3.fromWei(account1PrlTokenBalance, "ether") '5000'
Сработало! Что делать дальше, - спросите вы.
Можете протестировать этот код в Ethereum testnet или создать веб-приложение, позволяющее пользователям взаимодействовать с созданным контрактом (обратите внимание, что код работает в Truffle в папке app). Можете реализовать дедлайн, рыночную капитализацию и т. д. Дайте волю воображению, будьте одним из первых!
Сообщество Ethereum растёт изо дня в день, и хотя инструментов для работы пока не много, Truffle и OpenZeppelin отлично справляются с задачами и облегчают работу разработчикам.