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

Tezos — это блокчейн, созданный для настройки, адаптации и добавления функций и функций с помощью проверенного механизма обновления в сети. Это важный навык — научиться и понять, как подключить приложение Vuejs к смарт-контрактам, построенным на блокчейне Tezos. Владение токенами Tezos (tez) позволяет взаимодействовать с блокчейном Tezos. Вы можете хранить tez в цифровых кошельках, поддерживаемых Tezos. Дополнительную информацию о блокчейне Tezos вы можете найти здесь.

В этой статье вы узнаете, как взаимодействовать со смарт-контрактом для мемо-приложения, развернутого на блокчейне Tezos из приложения Vue. Чтобы продолжить изучение этой статьи, вам необходимы базовые знания Vue и Vuex; полный код проекта вы можете найти здесь.

Создание нашего приложения

vue create tez_memo && vue add vuex

Чтобы начать с нашего приложения Vue, мы создадим приложение Vue и добавим Vuex из CLI.

Выберите вариант конфигурации и продолжите настройку приложения. Для этой статьи мы выберем конфигурацию «По умолчанию ([Vue 3] babel, eslint)». После создания приложения вам нужно будет установить все необходимые зависимости для проекта.

yarn add @airgap/beacon-sdk @taquito/beacon-wallet @taquito/taquito bignumber.js buffer path-browserify stream-browserify

Кроме того, нам нужно будет настроить webpack для устранения ошибок полифилла из-за webpack 5 в файле vue.config.js, который мы включим.

const { defineConfig } = require("@vue/cli-service");
var webpack = require('webpack');
module.exports = defineConfig({
//…
configureWebpack: {
  resolve: {
    fallback: {
    path: require.resolve("path-browserify"),
    stream: require.resolve("stream-browserify"),
    buffer: require.resolve("buffer"),
    crypto: false,
    },
  },
  plugins: [
    new webpack.ProvidePlugin({
      Buffer:  ["buffer",  "Buffer"],
    }),
  ],
},
//…
});

Настройка хранилища и поставщика RPC

📂store
┣ 📜actions.js
┣ 📜getters.js
┣ 📜index.js
┗ 📜mutations.js

Следующим шагом будет настройка состояния и действий. Мы создадим следующие файлы в папке магазина.

Я сосредоточусь на настройке подключения Tezos, поэтому перейду к файлу действий. Вы можете просмотреть содержимое других файлов store здесь.

В actions.js мы настроим подключение Tezos RPC к ithacanet, тестовой сети на блокчейне Tezos. Смарт-контракт, с которым мы будем работать, развернут на ithacanet. Для подключения к ithacanet у нас будет следующий код.

import { TezosToolkit } from "@taquito/taquito";
import { BeaconWallet } from "@taquito/beacon-wallet";
import { ColorMode, NetworkType } from "@airgap/beacon-sdk";
import { CONTRACT_ADDRESS } from "@/utils";
import BigNumber from "bignumber.js";
// Set the network
const network = { type: NetworkType.ITHACANET };
// initialize the SDK
const Tezos = new TezosToolkit("https://ithacanet.ecadinfra.com");
const wallet = new BeaconWallet({
  name: "Tez-memo",
  preferredNetwork: network.type,
}); // Takes the same arguments as the DAppClient constructor
Tezos.setWalletProvider(wallet);
// setting the color mode for beacon wallet
wallet.client.setColorMode(ColorMode.DARK);
const getContract = async () => await Tezos.wallet.at(CONTRACT_ADDRESS);

В строке 9 я настроил новый TezosToolkit со ссылкой RPC на тестовую сеть ithacanet; проверьте здесь ссылки на другие узлы RPC. В строке 10 мы устанавливаем соединение с Beacon; это позволяет нашему децентрализованному приложению (dApp) взаимодействовать с кошельком. Для получения дополнительной информации о Beacon вы можете посмотреть их официальную документацию.

Следующим шагом будет передача кошелька методом setWalletProvider на Tezos. В строке 17 у нас есть функция, которая подключается к смарт-контракту. Метод at принимает в качестве параметра адрес контракта (уникальный идентификатор смарт-контрактов, развернутых в блокчейне Tezos); кошелек для подписания контракта вызывает этот вариант использования. Кроме того, вы можете настроить другие форматы для подписания вызовов контракта через TezBridge или inMemory (используя закрытый ключ учетной записи). Подробнее о других форматах заключения договорных звонков вы можете прочитать здесь.

Подключение кошелька

Следующим действием будет установка подключения к кошельку в нашем dApp; для этого необходимо запросить разрешение на подключение к кошельку. В файле actions.js у меня есть функция connectWallet; он запрашивает разрешение на подключение к кошельку.

...
    async connectWallet({ dispatch }) {
    try {
      await wallet.requestPermissions({
        network: network,
      });
      dispatch("checkWalletConnection");
    } catch (error) {
      console.log(error);
    }
  },
...

В строке 4 запрос на подключение к кошельку инициируется методом requestPermissions; эта функция передается кнопке подключения кошелька в приложении vue. При нажатии кнопки «Подключить кошелек» появится модальное окно с различными вариантами кошелька.

В этой статье я буду использовать кошелек храма, кошелек расширения браузера. Скачать расширение можно здесь. Как только запрос на подключение будет одобрен, действие connectWallet отправит checkWalletConnection.

...
    async checkWalletConnection({ commit }) {
    try {
      const activeAccount = await wallet.client.getActiveAccount();
      let pkh;
      if (activeAccount) {
        // If defined, the user is connected to a wallet.
        pkh = activeAccount.address;
        commit("updatePkh", pkh);
        commit("updateConnected", true);
      } else {
        commit("updatePkh", "");
        commit("updateConnected", false);
      }
    } catch (error) {
      console.log(error);
    }
  },
...

Это действие проверяет, находится ли учетная запись с активным разрешением в кошельке в строке 4. Если активная учетная запись существует, pkh (хэш открытого ключа)/адрес учетной записи присваивается состоянию pkh, а состояние подключения истинно. Когда активной учетной записи не существует, параметрconnect имеет значение false, а pkh — пустая строка. Также необходимо отключить разрешение кошелька, и этого можно добиться, вызвав метод clearActiveAccount в кошельке:

...
  async disconnectWallet({ dispatch }) {
    await wallet.clearActiveAccount();
    dispatch("checkWalletConnection");
  },
...

Повтор сеанса с открытым исходным кодом

OpenReplay – это пакет для воспроизведения сеансов с открытым исходным кодом, который позволяет вам видеть, что пользователи делают в вашем веб-приложении, помогая вам быстрее устранять неполадки. OpenReplay размещается на собственном сервере для полного контроля над вашими данными.

Начните получать удовольствие от отладки — начните использовать OpenReplay бесплатно.

Взаимодействие со смарт-контрактом

После настройки подключения к кошельку для приложения следующим шагом будет настройка взаимодействия смарт-контрактов и доступа к хранилищу контрактов. Вы можете просмотреть хранилище и методы смарт-контракта в смарт-контракте через сетевые обозреватели. Пример сетевого обозревателя для Tezos — Better Call Dev. Для предварительного просмотра контракта вам нужно будет ввести адрес контракта и выполнить поиск на платформе. Найти смарт-контракт для этого проекта в проводнике здесь

На изображении показана структура хранилища. У нас есть ключ для установки идентификатора для новой заметки, карта с парой идентификатора и адреса учетной записи в качестве ключа и объекта заметки в качестве значения, а также пользовательская карта, которая использует адрес учетной записи в качестве ключа и набор идентификаторов заметок, привязанных к адрес аккаунта.

На этом изображении видно, что смарт-контракт имеет четыре метода: addMemo, deleteMemo, toggleMemoStatus и updateMemo.

Доступ к хранилищу контрактов

Следующим действием будет доступ к хранилищу контрактов и отображение заметок, существующих в хранилище. Я буду делать это в функции getMemoList в файле действий.

...
async getMemoList({ state, commit }) {
  commit("updateLoading", true);
  try {
    let active_memo = [];
    let done_memo = [];
    if (state.connected) {
      const contract = await getContract();
      const storage = await contract.storage();
      const storage_user_memos = await storage.users.get(state.pkh);
      const user_memos = storage_user_memos.map((val) => new BigNumber(val).toNumber());
      console.log(user_memos);
      for (let index = 0; index < user_memos.length; index++) {
        const memo = await storage.memos.get({
          owner: state.pkh,
          id: user_memos[index].toString(),
        });
        const formated_memo = { ...memo, id: new BigNumber(memo.id).toString() };
        if (!memo.done) {
          active_memo.push(formated_memo);
        } else {
          done_memo.push(formated_memo);
        }
      }
    }
    commit("updateActiveMemo", active_memo);
    commit("updateDoneMemo", done_memo);
  } catch (error) {
    console.log(error);
  } finally {
    setTimeout(() => {
      commit("updateLoading", false);
    }, 1000);
  } // end try catch
},
...

Вам нужно вызвать метод storage в контракте, чтобы получить доступ к хранилищу контракта, как показано в строке 9. Чтобы получить доступ к набору идентификаторов мемо для текущей подключенной учетной записи, вызовите метод get для пользователей и передайте ключ для значения для доступа ; в данном случае адрес, подключенный к dApp. Это вернет массив больших чисел. В строке 11 мы перебираем набор, чтобы преобразовать большие числа в числа. Обновленный набор перебирается, чтобы получить все заметки с идентификатором, принадлежащим активному адресу в строках с 13 по 25. Впоследствии состояния active_memo и done_memo обновляются заметками, возвращенными из хранилища.

Выполнение вызовов смарт-контрактов из приложения Vue

Из изображения 3 мы знаем, что смарт-контракт имеет четыре метода, с которыми можно взаимодействовать. Метод addMemo позволяет создать новую заметку, принимая строку заметки в качестве значения.

...
async addMemo({ dispatch }, memo) {
  try {
    const contract = await getContract();
    const op = await contract.methods.addMemo(memo).send();
    await op.confirmation()
    dispatch("softUpdateMemoList");
  } catch (error) {
    console.log(error);
  }
},
...

В строке 4 смарт-контракт инициируется вызовом метода send(). Строка 5 ожидает подтверждения транзакции в блокчейне и отправляет действие the softUpdateMemoList. softUpdateMemoList похож на getMemoList, с той лишь разницей, что он не обновляет состояние loading.

Следующий метод смарт-контракта — deleteMemo; это удаляет существующую заметку учетной записью, которая создала заметку. Он принимает идентификатор заметки в качестве параметра. N/B: идентификатор заметки должен быть строкой.

...
async deleteMemo({ dispatch }, id) {
  try {
    const contract = await getContract();
    const op = await contract.methods.deleteMemo(id).send();
    await op.confirmation()
    dispatch("softUpdateMemoList");
  } catch (error) {
    console.log(error);
  }
},
...

Чтобы переключить памятку, вы вызовете метод toggleMemoStatus в контракте. deleteMemo также принимает идентификатор заметки и должен вызываться из учетной записи, которая создала заметку.

...
async toggleMemoStatus({ dispatch }, id) {
  try {
    const contract = await getContract();
    const op = await contract.methods.toggleMemoStatus(id).send();
    await op.confirmation()
    dispatch("softUpdateMemoList");
  } catch (error) {
    console.log(error);
  }
},
...

метод против методовОбъект

Метод updateMemo принимает в качестве параметра объект со свойствами memo и id. Ранее я инициировал вызовы смарт-контрактов в таком формате:

contract.methods.['smart contract method'].send()

Последовательность вызова контракта не будет работать, если вам нужно передать объект в качестве параметра методу смарт-контракта. Для этого вы будете использовать действие methodObject, которое показано в действии updatedMemo:

async updateMemo({ dispatch }, payload) {
  try {
    const contract = await getContract();
    const op = await contract.methodsObject.updateMemo(payload).send();
    await op.confirmation()
    dispatch("softUpdateMemoList");
  } catch (error) {
    console.log(error);
  }
},

в строке 4 вместо method используется methodObject.

Заключение

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

В этой статье мы прошли весь процесс интеграции смарт-контракта, развернутого на блокчейне Tezos, в приложение Vue. Если вы дошли до этого момента, вы сможете подключиться к кошельку и совершать вызовы смарт-контрактов в блокчейне Tezos. Если вы хотите научиться писать смарт-контракты, посмотрите эту документацию. Вы также можете найти полный код проекта здесь и живую версию приложения здесь. Ура.

Первоначально опубликовано на https://blog.openreplay.com 30 мая 2022 г.