Почему мы разделяем наше монорепозиторий и как мы работаем со смарт-контрактами

Во-первых, я думаю, что совершенно нормально помещать весь код в одно место, особенно в начале проекта. Просто делай дела. Не усложняйте. Однако, в конце концов, все усложняется. Работать со смарт-контрактами сложно, потому что после их развертывания они доступны, а обновление не всегда просто. Более того, другим частям вашего dApp нужен код контракта для взаимодействия с ними. В этой статье будет представлена ​​наша структура кода, используемая в FELToken, которая, как мы надеемся, сделает вещи масштабируемыми и простыми в обслуживании.

Основные компоненты

Каждое dApp обычно состоит из 2 основных компонентов: смарт-контрактов и веб-приложения, связывающегося с ними. Часто дополнительные библиотеки также взаимодействуют со смарт-контрактами. Для взаимодействия со смарт-контрактами вам всегда нужен адрес контракта и ABI.

Структура зависимостей не сложна. Все компоненты зависят от смарт-контрактов, в которых хранятся адреса развертывания и ABI контракта.

Почему не Монорепо?

Глядя на приведенную выше структуру, становится ясно, что нам придется обрабатывать обмен необходимыми файлами, если мы разделим компоненты. Так зачем нам разделять вещи? Зачем проходить эту дополнительную борьбу, если мы можем хранить все в одном месте?

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

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

Разделив код на несколько репозиториев, мы можем гарантировать, что все будет работать на каждой стадии разработки. Кроме того, мы можем использовать теги git для ссылки на правильные версии между репозиториями. Например, когда мы обновляем смарт-контракты, веб-приложение по-прежнему может ссылаться на более старую версию, пока она не будет обновлена. Такой подход гарантирует, что больше людей могут работать одновременно, не ломая вещи.

Как обменять ABI смарт-контракта?

Мы используем Brownie для развертывания смарт-контрактов. Мы также решили использовать GitHub для обмена файлами смарт-контрактов (адресами и ABI). Легко создать действие GitHub, которое автоматически развернет смарт-контракты и сохранит необходимые файлы в репозитории GitHub:

Затем в веб-приложении мы можем fetch получить необходимые файлы из GitHub на основе тега. Супер просто, верно? Что ж, есть еще одна сложная часть: локальное развитие.

Решение для местного развития

Запуск локального блокчейна Ganache — это хлеб насущный при разработке Web3. Одновременный запуск смарт-контрактов и веб-приложения неизбежен. Нам нужно убедиться, что мы не усложняем это, разбивая код на несколько репозиториев.

Мы решили решить эту проблему с помощью локального файлового сервера. Это может показаться слишком много, но это решает все красиво. Итак, в конце нашего сценария развертывания мы запускаем файловый сервер. Запустить файловый сервер в Python просто:

Затем в конце сценария развертывания нам нужно запустить server_build_directory(). Обязательно запустите эту функцию в самом конце, так как она блокирует выполнение. Вы можете прочитать наш полный сценарий развертывания здесь: deploy_dev.py. Когда сервер запущен, мы можем получать файлы так же, как и с GitHub. Нам просто нужно заменить URL-адрес GitHub на http://localhost:8100. Структура файлов остается прежней!

Самое замечательное в этом подходе то, что Brownie автоматически очищает локальные файлы разработки. Поэтому мы не коммитим локальные файлы в git.

Заключение

Наш подход не единственно правильный. Я видел, как люди используют разные стратегии для хранения смарт-контрактов, например, сохраняя их в виде пакета NPM. Затем этот пакет устанавливается в веб-приложение с помощью NPM. Это довольно удобно, если все ваши компоненты используют JavaScript. Проблема в том, что у нас есть библиотеки JavaScript и Python, взаимодействующие со смарт-контрактами, что делает решения для конкретных языков непрактичными.

Не забудьте подписаться на дополнительные руководства, если они вам пригодятся. Я пишу о нашем опыте работы с web3 во время разработки проекта @FELT_labs, создавая решение ИИ, сохраняющее конфиденциальность.