В седьмой части этой серии руководств по созданию DApp-приложений с помощью Ethereum мы показали, как создать внешний интерфейс приложения, настроить и развернуть пользовательский интерфейс для этой истории, над которой мы работали.
Пришло время сделать несколько развертываний и написать несколько заключительных функций.
Это восьмая часть серии по созданию децентрализованных приложений с использованием блокчейна Ethereum . Проект, который мы строим, называется «Бесконечная история». Полный проект можно найти на storydao.bitfalls.com . Его полный код находится на GitHub .
Вот схема всей серии:
- В первой части мы разрабатываем две версии локального блокчейна для разработки: версию Ganache и полную приватную версию PoA.
- Во второй части мы создаем и разворачиваем наш токен TNS.
- В третьей части мы рассмотрим, как скомпилировать, развернуть, протестировать и проверить наш собственный токен TNS, который совместим со всеми биржами и может использоваться в качестве обычного токена ERC20.
- В части 4 мы предпринимаем первые шаги к разработке Story DAO, включая белый список и тестирование.
- В пятой части мы рассмотрим добавление контента в историю и рассмотрим, как добавить участникам возможность покупать токены в DAO и добавлять материалы в историю.
- В части 6 мы приведем DAO к окончательной форме, добавив голосование, внесение в черный / черный список, а также распределение и снятие дивидендов, добавив при этом некоторые дополнительные вспомогательные функции для хорошей меры.
- В части 7 мы покажем, как создать интерфейс приложения, настроить и развернуть пользовательский интерфейс для этой истории, над которой мы работали.
- В этой заключительной части мы рассмотрим последние этапы развертывания приложения и написания нескольких заключительных функций.
самоубийца
Что-то может пойти очень, очень неправильно, и весь DAO каким-то образом разрушится — либо из-за взлома плохого и поспешно написанного кода, либо из-за невозможности создавать длинные циклы из-за слишком большого количества участников. (Слишком много избирателей в предложении могут также сломать систему; мы действительно не предприняли никаких мер предосторожности для этого!) На всякий случай это может быть полезно иметь эквивалент «большой красной кнопки». Во-первых, давайте обновим наш StoryDao:
function bigRedButton() onlyOwner external { active = false; withdrawToOwner(); token.unlockForAll(); }
Тогда давайте сделаем возможным разблокировать все токены одновременно в нашем контракте токенов:
/** @dev unlocks the tokens of every user who ever had any tokens locked for them */ function unlockForAll() public onlyOwner { uint256 len = touchedByLock.length; for (uint256 i = 0; i < len; i++) { locked[touchedByLock[i]] = 0; } }
Естественно, нам нужно добавить этот новый список адресов в контракт:
address[] touchedByLock;
И нам нужно обновить нашу функцию increotLockedAmount, чтобы добавить адреса в этот список:
/** @dev _owner will be prevented from sending _amount of tokens. Anything beyond this amount will be spendable. */ function increaseLockedAmount(address _owner, uint256 _amount) public onlyOwner returns (uint256) { uint256 lockingAmount = locked[_owner].add(_amount); require(balanceOf(_owner) >= lockingAmount, "Locking amount must not exceed balance"); locked[_owner] = lockingAmount; touchedByLock.push(_owner); emit Locked(_owner, lockingAmount); return lockingAmount; }
Мы также должны обновить требуемый интерфейс токена внутри контракта StoryDao, чтобы включить подпись этой новой функции:
// ... function getUnlockedAmount(address _owner) view public returns (uint256); function unlockForAll() public; }
С блоком active-story, который мы добавили ранее (неспособность запускать определенные функции, если флаг active
истории не установлен в true), это должно сработать. Никто больше не сможет тратить деньги, отправив их в контракт, и все токены будут разблокированы.
Владелец не принимает эфирных людей. Вместо этого становится доступна функция отвода, чтобы люди могли забрать свой эфир обратно, и обо всем позаботились.
Теперь наши контракты наконец готовы к развертыванию.
Как насчет самоуничтожения?
Есть функция, называемая selfdestruct
которая позволяет уничтожить контракт. Это выглядит так:
selfdestruct(address);
Вызов этого вызовет отключение соответствующего контракта, удаление его кода из состояния блокчейна и отключение всех функций, при отправке эфира по этому адресу на указанный адрес. В нашем случае это не очень хорошая идея: мы все еще хотим, чтобы люди могли отозвать свой эфир; мы не хотим отнимать это у них. Кроме того, любой эфир, отправленный прямо по адресу самоубийственного контракта, будет потерян навсегда (сожжен), потому что нет никакого способа вернуть его.
Развертывание контракта
Чтобы полностью развернуть смарт-контракты, нам нужно сделать следующее:
- развернуть в сети
- отправьте токены на адрес StoryDAO
- передать право собственности на токен-контракт StoryDao.
Пошли.
Развертывание мейннета
Для развертывания в mainnet нам нужно добавить новую сеть в наш файл truffle.js
:
mainnet: { provider: function() { return new WalletProvider( Wallet.fromPrivateKey( Buffer.from(PRIVKEY, "hex")), "https://mainnet.infura.io/"+INFURAKEY ); }, gasPrice: w3.utils.toWei("20", "gwei"), network_id: "1", },
К счастью, это очень просто. Это практически идентично развертыванию Rinkeby; нам просто нужно убрать количество газа (пусть оно рассчитает его самостоятельно) и изменить цену на газ. Мы также должны изменить идентификатор сети на 1, так как это идентификатор основной сети.
Мы используем это так:
truffle migrate --network mainnet
Здесь есть одно замечание. Если вы развертываете в сети, в которой вы ранее развернули (даже если вы просто развернули токен в сети и позже захотели развернуть StoryDao), вы можете получить эту ошибку:
Attempting to run transaction which calls a contract function, but recipient address XXX is not a contract address
Это происходит потому, что Truffle запоминает, где он развернул уже развернутые контракты, чтобы он мог использовать их в последующих миграциях, избегая необходимости повторного развертывания. Но если ваша сеть перезапустилась (например, Ganache) или вы сделали какие-то несовместимые изменения, может случиться, что сохраненный адрес больше не содержит этот код, поэтому он будет жаловаться. Вы можете обойти это путем сброса миграций:
truffle migrate --network mainnet --reset
Отправьте токены на адрес StoryDao
Получите адрес токена и адрес StoryDao из процесса развертывания.
Затем просто используйте MEW, как описано выше, чтобы отправить токены.
Если вы получаете ошибки Out of Gas, просто увеличьте лимит газа. Помните: остальная часть неиспользованного газа всегда возвращается, поэтому не стоит бояться потерять больше денег, чем расходы на транзакцию (отправка токенов должна быть не более 40000 газа).
Передача владения токеном StoryDao
Чтобы передать право собственности, нам нужно вызвать функцию TransferOwnership для токена. Давайте загрузим токен в MEW. На экране « Contracts
мы вводим адрес и ABI контракта (извлекаем его из папки /build
). Нажатие на Access позволит нам получить доступ к функциям в этом контракте в меню, из которого мы выбираем transferOwnership
.
Совет: достаточно включить только ABI функций, которые вы собираетесь вызывать: это не обязательно должен быть весь ABI токена! Вы можете просто включить ABI функции TransferOwnership, и все будет хорошо!
Затем мы выбираем нового владельца (адрес развернутого StoryDao) и разблокируем кошелек текущего владельца (тот же кошелек, с которого мы ранее отправляли токены).
После написания этого изменения мы можем проверить owner
функции только для чтения в контракте токена (то же меню, что и transferOwnership
). Это должен показать новый владелец сейчас.
Чтобы убедиться, что адрес StoryDao действительно содержит токены, мы можем выбрать функцию balanceOf
и ввести адрес _owner
поле _owner
, а затем нажать « Читать» :
Действительно, 100 миллионов токенов находятся в адресе StoryDao.
Совет: мы могли бы также выполнить отправку токена и владение как часть шага развертывания. Попробуйте выяснить, как в тестовой среде.
верификация
Согласно части 3 этой серии, нам было бы очень полезно проверить контракты как DAO, так и токена на Etherscan. Эта зеленая галочка может иметь большое значение.
Следуйте инструкциям в этой части, чтобы проверить ваши контракты. Обратите внимание, что на этапе проверки вы должны пометить оптимизатор как активный, поскольку мы оптимизируем наш код для более дешевого развертывания!
Развертывание в Интернете
Чтобы развернуть веб-интерфейс StoryDao, следуйте инструкциям из «обычного» мира веб-разработки. Поскольку в данном случае все это статический код, вы даже можете разместить его на страницах GitHub или что-то подобное.
Читайте о некоторых вариантах здесь и здесь .
Когда страница откроется, настройте пользовательский интерфейс на использование адресов контрактов, которые мы получили на этапе миграции. Кроме того, зарегистрируйте имена ENS для токена и StoryDao, и вы можете сохранить статический и фиксированный веб-интерфейс, жестко закодировать адреса, а затем только изменить адрес Ethereum, на который указывают имена ENS.
Вывод
На этом учебное пособие по DAO завершено. Мы надеемся, что это помогло вам осознать сложности разработки Solidity, но мы также надеемся, что это прояснило некоторые вещи и сделало вас более любопытными.
Как всегда, лучший способ учиться — это делать. Экспериментируйте, делайте ошибки, перезагружайтесь и перестраивайте. Разработка блокчейнов такого типа пользуется большим спросом, и она становится все более популярной, поэтому у вас есть возможность попасть на первый этаж.
Удачи!
PS Если вам понравился этот урок, не стесняйтесь пинговать автора в Twitter . Если у вас есть жалобы, предложения, идеи и т. Д., Пожалуйста, отправляйте их в хранилище на GitHub!