Перед разработкой собственного блокчейна ваша команда должна четко понимать, для чего необходим блокчейн и какой бюджет вы сможете выделить на его содержание.
Проектирование и запуск блокчейна имеют свои нюансы. Их можно легко упустить при планировании, если вы неверно оценили объем и сложность задачи.
Чтобы помочь проектам избежать таких ошибок, руководитель отдела исследований MixBytes Сергей Прилуцкий подготовил пошаговое руководство по запуску блокчейна.
Определение круга технических задач
Задача блокчейна — принимать от пользователей транзакции и точным и неоспоримым способом обрабатывать каждую из них. Результаты работы каждой транзакции записываются в общедоступную базу данных (state database) на каждой машине блокчейн-сети. Любой участник может воспроизвести и перепроверить эту базу данных, если у него есть данные о ее первоначальном состоянии и журнал всех транзакций или блоков.
Чтобы правильно выбрать блокчейн, техническим специалистам прежде всего нужно определить типы транзакций и как будет работать каждая из них. Для классификации удобно использовать традиционные серверные ресурсы: процессор, оперативная память, сетевой трафик, хранилище (cpu, mem, network, storage).
Некоторые транзакции требуют мало оперативной памяти (ничего не вычисляют), зато они могут изменить сразу несколько балансов и записать большой объем данных в хранилище (storage). Другие транзакции сильно нагружают процессор, чтобы произвести криптографические вычисления, но результатом будет единственное небольшое значение, записанное в хранилище. В первом случае больше работы достанется жесткому диску и оперативной памяти, а во втором — процессору. Эти параметры могут сильно повлиять на стоимость серверов вашего блокчейна, поэтому оценка характера транзакций — важная часть технического дизайна.
Помимо транзакций большое значение имеют сценарии работы блокчейна: какое количество каких транзакций от какого количества аккаунтов сеть обрабатывает в единицу времени. Это может быть всего десяток аккаунтов, каждый из которых отправляет много транзакций в сеть, или постоянный приток тысяч новых аккаунтов, которые заключают одну небольшую сделку. Нужно понимать, что сети для игр, финтех-приложений или криптографических протоколов сильно отличаются по характеру нагрузки на ноды.
Любая логика, сложнее чем просто перевод токенов с адреса на адрес, требует использования определенного кода (смарт-контракты, runtime и т.п.). Работая над проектом блокчейна необходимо учесть, какая виртуальная машина для исполнения такого кода будет использоваться в проекте:
Вариант 1: специализированная виртуальная машина (VM)
Примеры: EVM (Ethereum), TVM (TON)
Специализированные VM, как правило, ограничены и заточены строго под смарт-контракты своей платформы. Они порождают более предсказуемые результаты, являются наиболее безопасными и точно учитывают ресурсы, потраченные на обработку транзакций.
Вариант 2: стандартная виртуальная машина
Примеры: Web Assembly в EOS, Parity Substrate (Polkadot).
WebAssembly (WASM) — это веб-стандарт, используемый для создания кода, исполняемого на стороне клиента и более производительного, чем JavaScript. Теоретически, смарт-контракты под WASM можно писать на любом языке, но для блокчейнов лучше подходят низкоуровневые языки (C, C++, Rust и т.д.), иначе получившийся код будет плохо оптимизирован.
WASM также ведет учет потраченных на исполнение ресурсов. Имея большую функциональность контрактов, WebAssembly менее безопасна, чем специализированная виртуальная машина.
Вариант 3: обработка транзакций нативным кодом
Примеры: Hyperledger Fabric, Cosmos.
Обработка нативным кодом используется, когда код, обрабатывающий транзакцию, фактически встроен в ноду. Минус данного варианта — наименьшая безопасность и детерминированность обработки транзакций; плюс — высокая функциональность (разработчикам доступны любые функции языка без ограничений).
Еще одним из критериев выбора блокчейна является способ обновления кода контрактов. При эксплуатации системы неизбежно будут возникать ошибки и необходимость добавлять и изменять функциональность системы. В современных блокчейнах эти задачи можно решать несколькими способами.
Вариант 1: пользовательские смарт-контракты
Примеры: смарт-контракты в Ethereum, EOS, TON, Parity Substrate (с модулем пользовательских смарт-контрактов WASM или EVM).
В этой схеме любой пользователь может создать смарт-контракт или несколько, соединенных в сложную систему. Контракты можно размещать и обновлять без взаимодействия с валидаторами сети.
Эта схема — наиболее гибкая. Она позволяет строить системы контрактов произвольной сложности, но требует более сложной логики работы ноды, потому что код контрактов является недоверенным и может содержать все что угодно. Поэтому нужно, чтобы нода исполняла такой код крайне осторожно, ограничивая его по времени и запрашиваемым данным, и не позволяла бы влиять на консенсус.
Вариант 2: код runtime, контролируемый валидаторами
Примеры: runtime в Parity Substrate, Application в Cosmos.
Данную схему можно представить в виде одного большого смарт-контракта, который обрабатывает все виды транзакций. Код проверяют валидаторы и голосуют за применение изменений, после чего новая логика начинает работать. При этом разработчики избавлены от большого числа ограничений и могут создавать код runtime из набора готовых модулей.
Эта схема делает более сложным изменение кода, который обрабатывает транзакции, но позволяет не делать дополнительные проверки безопасности. Валидаторы в данной схеме обязаны проверять изменения и не пропускать уязвимый код, иначе рискуют получить неработоспособный блокчейн.
Зато разработчики такого «runtime» получают в распоряжение гораздо больше возможностей и ресурсов, чем в схеме с пользовательскими контрактами. Эта схема особенно актуальна для парачейнов (небольших дочерних цепочек с отдельным функционалом, являющимися частями большой системы из множества блокчейнов).
Без понимания характера транзакций, особенностей виртуальной машины и логики работы смарт-контрактов проект может крайне неоптимально использовать блокчейн. Например, поддерживать работу дорогостоящего ПО ради простейших операций или проводить рискованные обновления основного кода ноды ради небольших исправлений в логике.
Ограничения блокчейна
При запуске собственного блокчейна нужно оценить технические требования клиента и понять, насколько они выполнимы.
Одним из таких требований является время «исполнения» транзакции на стороне клиента. Частой ошибкой является оценка скорости только на основе tps (количество транзакций в секунду).
Разработчики, как правило, оценивают tps как количество транзакций в блоке ко времени блока. Например, под «1000 tps» имеется в виду, что время между блоками равно 1 секунде, а в блоке может быть до 1000 транзакций. Это не значит, что блокчейн обрабатывает одну транзакцию за 0.001 секунды, поскольку время обработки транзакции зависит от времени производства блока.
Если время производства блока — 3 секунды, то время обработки одной транзакции может достигать 3-х секунд (от момента отправки транзакции и до появления следующего блока). 3000 tps (при максимуме в 1000 транзакций в блоке) можно достичь только при параллельной отправке транзакций с разных аккаунтов.
Еще одно важное ограничение современных блокчейнов — это число валидаторов (серверов, производящих и подтверждающих блоки). Произведя блок, валидаторы обязательно приходят к согласию (консенсусу) относительно него. Время производства блока зависит от числа валидаторов и числа сообщений, которыми им надо обменяться. Для любого сетевого консенсуса требуется согласие минимум 1/2 N + 1 валидаторов, а с полными гарантиями безопасности — согласие 2/3 N + 1 валидаторов. Данные значения являются фундаментальными, обойти их нельзя, так как они обеспечивают устойчивость сети к злонамеренному поведению участников.
Если вы планируете запускать блокчейн, забудьте о мгновенных ответах клиентам и миллионах валидаторов. Такие масштабы достижимы только с появлением полноценных квантовых технологий связи и криптографических вычислений.
Планирование запуска и поддержки сети
Предположим, вы выбрали блокчейн и собираетесь его запускать. Каковы дальнейшие шаги?
Прежде всего, необходимо выбрать конкретную технологию, оценить риски и трудозатраты на реализацию проекта, а также учесть ограничения конкретных решений. Решение может быть уже проверенным в реальных условиях или находиться на стадии разработки.
В случае, если вы запускаете собственноручно разработанное решение, изучите наиболее близкие аналоги. Так вы сможете сэкономить время и учесть проблемы, которые до вас уже решили другие команды.
Тестирование сети — это проверка работоспособности блокчейна с числом валидаторов, приближенным к реальности. Если блокчейн подразумевает 100 валидаторов, необходимо убедиться, что сеть работоспособна под нагрузкой.
При тестировании будет подготовлена инфраструктура для автоматического разворачивания сети с несколькими валидаторами, что пригодится на последующих этапах.
Без тестирования есть серьезный риск, что сетевой консенсус содержит ошибки или уязвимости, особенно если это собственное решение, а не хорошо известный алгоритм. Собирать информацию о проблемах в уже запущенной сети будет очень непросто.
Testnet нужен, чтобы пользователи и команда могли опробовать в ней то, что будет работать в основной сети (mainnet). Весь функционал основной сети должен присутствовать в тестовой, а клиентские приложения — поддерживать обе сети. Благодаря точности смарт-контрактов, тестирование рабочих продуктов можно провести с 99% точностью, с реальными балансами реальных пользователей.
В testnet можно раздать токены, проверить, как валидаторы запускают свои ноды, провести первые сделки вместе с активными пользователями, а полученные результаты позже использовать в mainnet.
Некоторое ПО необходимо будет поддерживать сразу после запуска тестовой сети (например, веб-интерфейс для валидаторов, мониторинг или обозреватель блоков). Информация, полученная на этапе запуска этих сервисов в тестовой сети, пригодится при «чистовом» запуске в mainnet.
Именно на этом этапе будет видно качество работы команды проекта — насколько стабильно запущенное ПО, насколько качественно была написана документация, насколько быстро потенциальные валидаторы смогли поднять требуемый софт, сколько раз пришлось вносить исправления и т.д.
Обычно в роли валидаторов сети выступают независимые компании, поэтому собрать их вместе и заставить синхронно выполнить какие-то действия почти невозможно. Все процедуры должны предусматривать произвольный порядок действий валидаторов, учитывать их географическое распределение и степень неподготовленности.
Наиболее популярный вариант выбора валидаторов на сегодняшний день — процедуры, предусмотренные алгоритмами DPoS. В этом случае владельцы токенов голосуют своими балансами за валидаторов. Топ валидаторов, набравших большинство голосов-токенов получают право производить блоки. В proof-of-authority (POA) сетях и коропоративных блокчейнах, ситуация аналогична, но вместо балансов токенов используются голоса других валидаторов.
Перед стартом основной сети нужно сформировать начальный список валидаторов и решить, в какой момент начнется полноценное производство блоков. Технически команда может сразу прописать всех валидаторов в начальных блоках сети или запустить сначала только своих валидаторов, а потом постепенно заменять их на новых.
Запуск mainnet должен сопровождаться активным мониторингом. Желательно, чтобы сводная информация от всех валидаторов была представлена в одном сервисе — так команда проекта сможет более активно реагировать на проблемы в сети.
Новые требования также предъявляются к работе обозревателя блоков — главного внешнего сервиса сети. Он должен автоматически переключаться на запасные сервера в случае сбоев, так как информация о транзакциях крайне важна пользователям и команде проекта. Также может потребоваться резервное копирование, если обозреватель хранит предоставленную пользователями информацию (например, верификация кода контрактов в Etherscan).
Довольно капризным в плане поддержки на этом этапе может являться мост — ПО, которое позволяет переносить токены из одного блокчейна в другой. От его работы зависят балансы реальных пользователей, поэтому необходимо уделить особое внимание его безопасности.
После запуска основной сети работа команды не прекращается, особенно если блокчейн построен на основе существующих решений. Базовый код тоже развивается, и в нем накапливаются важные исправления ошибок и оптимизации. Эти изменения необходимо переносить в проект и своевременно обновлять код блокчейн-нод.
На этом этапе очень важна разработанная документация и процедуры, которые должны были быть опробованы в тестовой сети. При обновлении кода не должно происходить накладок, потому что в этом случае валидаторы теряют деньги, время и репутацию. В mainnet может существенно меняться состав валидаторов, и в случае их недостаточной поддержки или некачественной документации это может привести к проблемам в работе сети.
Заключение
При правильном подходе запуск блокчейна на базе уже работающих решений не несет серьезных рисков. Как правило, проблемы носят экономический или организационный характер, не связанный с внутренним кодом нод.
Построенные на основе публичных сетей (Ethereum, EOS) решения являются достаточно надежным ПО, доступным пользователям интернета без ограничений. Этим свойством не могут похвастаться централизованные финансовые системы: выставить в открытый доступ банковское API или базу данных с критичной информацией без регистрации, логинов/паролей и мониторинга не представляется возможным.
Хотя разработка и запуск блокчейна довольно затратны, реальная эксплуатация может приятно удивить участников безопасностью, саморегуляцией и способностью сети сохранять работоспособность и точность исполнения транзакций в сложных условиях.
Источник: forklog.com