Этот пост предназначен для всех, кто ищет подробное руководство по разработке и развертыванию приложения на основе блокчейна (в данном случае Ethereum) с использованием Vue.js для создания интерфейса и Truffle. @ Drizzle / vue-plugin для добавления суперспособностей блокчейна.
Репозиторий готового проекта можно найти здесь.
Предпосылки
Для этого урока вам понадобится несколько основных инструментов, установленных в вашей системе. Примечание: эти инструкции были написаны для системы Mac / Linux, но также должны применяться к Windows.
Установить узел
Если на вашем компьютере нет Node.js, возможно, вы захотите вернуться назад. Рекомендуемая версия для этого руководства: 10.16.1.
Чтобы легко переключаться между версиями Node для каждого проекта, я бы рекомендовал nvm.
Установить Truffle
Truffle - это набор инструментов, предназначенных для создания, компиляции, тестирования и развертывания смарт-контрактов. Установить глобально.
npm install -g truffle
Установить Vue CLI
Vue CLI - это самый быстрый способ скаффолдинга приложения Vue.js с помощью некоторых распространенных пакетов и инструментов. Установите это также глобально.
npm install -g @vue/cli
А теперь приступим!
Инициализация приложения
Создайте новое приложение Vue с помощью Vue CLI.
vue create guestbook
Вам будет предложено выбрать дополнительные пакеты для включения в свое приложение. Выберите все, что вы хотите использовать в своем проекте, но не забудьте включить Vuex, поскольку он будет служить связующим звеном между интерфейсом Vue и вашими смарт-контрактами. Это достигается за счет использования Drizzle, еще одного продукта Truffle, который отслеживает состояние смарт-контрактов и обеспечивает легкий доступ к методам, данным и событиям.
После успешного создания приложения инициализируйте Truffle в корне проекта.
truffle init
Это создаст несколько файлов и папок. Ваша структура каталогов должна выглядеть так:
Откройте truffle-config.js
и измените module.exports
, чтобы Truffle поместил выходные данные сборки JSON в папку src
, где интерфейсная программа может получить к ней доступ.
contracts_build_directory: "./src/contracts",
Теперь мы можем написать простой договор с гостевой книгой!
Написание контракта
Внутри папки contracts
(в корне проекта, а не в src / контрактах) создайте новый файл с именем Guestbook.sol
и создайте контракт.
pragma solidity >=0.4.21 <0.6.0; contract Guestbook { event SignatureAdded(string message, bytes32 name); bytes32[] guests; function signBook(bytes32 name) public { guests.push(name); emit SignatureAdded("New guest signature!", name); } function getNames() public view returns (bytes32[] memory) { return guests; } }
В первой строке объявляется, какую версию компилятора Solidity следует использовать в этом контракте. Для наших целей мы будем использовать тот же диапазон версий, что и контракт, созданный при запуске truffle init
.
Следующий блок - договор. Сначала мы заставляем событие запускаться всякий раз, когда добавляется подпись. Затем мы создаем массив для хранения имен. Затем метод для передачи имени в массив и отправки события всем, кто его слушает. Наконец, мы создаем метод, который возвращает список имен.
Контракт готов к развертыванию! Но сначала нам нужно создать миграцию, чтобы сообщить Truffle о нашем новом контракте. Внутри папки migrations
создайте новый файл миграции с именем 2_deploy_guestbook.js
. Добавьте следующее содержимое:
const Guestbook = artifacts.require("Guestbook"); module.exports = function(deployer) { deployer.deploy(Guestbook); };
Вернувшись в консоль в корневом каталоге проекта, инициализируйте консоль Truffle dev.
truffle develop
Вы будете вознаграждены своим личным блокчейном! Есть список адресов и закрытых ключей, а также мнемоника, которая понадобится вам для подключения к этому кошельку в другом месте. Вы заметите, что ваша консоль изменилась на truffle(develop)>
. Чтобы скомпилировать и перенести контракты одним махом, просто запустите:
migrate
Полезный совет - во время разработки вы можете вместо этого запустить:
migrate --reset
чтобы каждый раз при миграции начинать с чистого листа и обеспечивать распространение изменений в ваших контрактах.
Если все пойдет хорошо, вы должны увидеть кучу данных, связанных с успешным развертыванием контакта в блокчейне разработчика.
Создание приложения Vue
Откройте вторую консоль, так как нам нужно держать Truffle REPL под рукой для имитации нашей цепочки блоков Ethereum. Зайдите в корень вашего проекта и установите Drizzle Vue Plugin.
npm install @drizzle/vue-plugin
Затем перейдите в папкуsrc
и создайте файл с именем drizzleOptions.js
. Этот файл будет содержать конфигурацию для Drizzle. Добавьте следующий код:
import Guestbook from "@/contracts/Guestbook.json"; const options = { web3: { block: false, fallback: { type: "ws", url: "ws://127.0.0.1:9545" } }, // The contracts to monitor contracts: [Guestbook], events: { Guestbook: ["SignatureAdded"] }, polls: { // check accounts ever 15 seconds accounts: 15000 } }; export default options;
Здесь мы сообщаем Drizzle, где расположены артефакты сборки контракта, регистрируем контракт гостевой книги и сообщаем Drizzle, какие события он должен прослушивать, которые могут быть сгенерированы контрактом.
Откройте main.js
и сделайте так:
import Vue from "vue" import App from "./App.vue" import store from "./store" import drizzleVuePlugin from "@drizzle/vue-plugin" import drizzleOptions from "./drizzleOptions" Vue.config.productionTip = false Vue.use(drizzleVuePlugin, { store, drizzleOptions }) new Vue({ store, render: h => h(App) }).$mount("#app")
Здесь мы импортируем магазин Vuex, плагин Drizzle и только что созданный файл параметров. Затем мы говорим нашему приложению использовать плагин и передаем файл store и options в качестве параметров плагину.
Откройте App.vue
и отредактируйте раздел шаблона. Обязательно удалите любой шаблонный код, сгенерированный Vue CLI, например компоненты HelloWorld или нежелательные стили:
<template> <div v-if="isDrizzleInitialized" id="app"> <h1>Sign the Guestbook</h1> <drizzle-contract-form contractName="Guestbook" method="signBook" :placeholders="['Name']" /> <h2>Guests:</h2> <ul v-if="getNames"> <li v-for="(name, i) in getNames" :key="i">{{ utils.toUtf8(name) }}</li> </ul> </div> <div v-else> Loading application... </div> </template>
Во-первых, шаблон содержит v-if/else
в корне. Если Drizzle еще не инициализирован, данные вашего смарт-контракта не будут доступны, и вы тем временем захотите отобразить что-нибудь еще.
Существует специальный компонент под названием drizzle-contract-form
, который регистрируется при установке подключаемого модуля Drizzle. Учитывая имя контракта и метод, он будет генерировать входные данные, соответствующие входным параметрам, ожидаемым контрактом. Вы также можете установить массив заполнителей, которые отображаются в порядке значений параметров.
Следующий раздел получает список имен и перебирает их в неупорядоченном списке. Вскоре мы создадим метод getNames
, но заметим, что преобразование применяется к значениям списка. Нам нужно преобразовать байты, возвращаемые смарт-контрактом, в строки utf-8, если вы не предпочитаете отображать шестнадцатеричный код. Для этого мы привезем несколько утилит.
Вот раздел файла the<script>
:
<script> import { mapGetters } from "vuex" export default { name: "app", computed: { ...mapGetters("drizzle", ["drizzleInstance", "isDrizzleInitialized"]), ...mapGetters("contracts", ["getContractData"]), getNames() { let data = this.getContractData({ contract: "Guestbook", method: "getNames" }); if (data === "loading") return false; return data }, utils() { return this.drizzleInstance.web3.utils } }, created() { this.$store.dispatch("drizzle/REGISTER_CONTRACT", { contractName: "Guestbook", method: "getNames", methodArgs: [] }) } } </script>
Вот разбивка:
- Импортируйте
mapGetters
из Vuex, чтобы разрешить доступ к модулям хранилища Vuex, созданным плагином как вычисляемые свойства в нашем компоненте. См. Их документацию для получения дополнительной информации о том, как работает mapGetters. - Используйте
mapGetters
, чтобы импортировать несколько функций дождя из магазина. Нам нуженdrizzleInstance
для его утилит для преобразования текста.isDrizzleInitialized
возвращает логическое значение, которое мы можем использовать для условного рендеринга приложения и показывать какой-то индикатор «загрузки», когда оно еще не совсем готово. Наконец,getContractData
позволяет нам передавать имя и метод контракта и получать данные о его состоянии в реактивном режиме. Аккуратный! - Получите список имен гостевых книг с помощью
getContractData
. Проверьте возвращаемое значение, чтобы ничего не сломать в макете. - Импортируйте утилиты из
drizzleInstance
для преобразования шестнадцатеричного кода в читаемый текст. Экземпляр Drizzle расширяет web3.utils - ознакомьтесь с документацией, чтобы лучше понять типы доступных операций. - Когда компонент создан, зарегистрируйте контракт, метод и аргументы, используя действие
REGISTER_CONTRACT
из плагина. Это устанавливает контракт в Drizzle и делает его данные и функции доступными для вашего приложения, включая методgetContractData
.
Мы готовы запустить приложение!
Запуск приложения!
В вашем терминале:
npm run serve
Вы также можете использовать yarn serve
, если вам нравится такой вкус. После успешного построения сервер разработки должен запуститься.
Перейдите к одному из URL-адресов. Мы собираемся использовать Metamask в этом примере, но вы можете использовать любой другой браузер web3, если вы можете импортировать учетную запись и настроить URL-адрес RPC.
Если вы используете Metamask и не хотите терять текущий кошелек, убедитесь, что вы экспортировали исходную фразу (Настройки - ›Безопасность и конфиденциальность).
Выйдите из Metamask, затем на экране входа нажмите Импортировать с использованием начальной фразы учетной записи. Используйте начальную фразу, предоставленную truffle develop
, и ваш кошелек должен заполниться учетными записями, отображаемыми в консоли Truffle. Теперь в вашем приложении вы должны увидеть поле ввода, в котором вы можете добавить имя в список и отправить его в список. Попробуй! Через несколько секунд вы должны увидеть имя, которое появится в списке ниже.
Вы сделали это! В следующей части этой серии мы развернем смарт-контракты в тестовой сети Ropsten Ethereum. Следите за обновлениями!