Introducing 

Prezi AI.

Your new presentation assistant.

Refine, enhance, and tailor your content, source relevant images, and edit visuals quicker than ever before.

Loading…
Transcript

Частные PoA сети на базе Parity Ethereum

Константин Нархов

Нархов Константин

Об авторе

Основная сфера интересов — программирование для встроенных систем, IoT и разработка веб-интерфейсов для автоматизации доступа к распределенным системам. В настоящий момент занимаюсь исследованием способов интеграции децентрализованной сети IoT устройств в частную PoA сеть на blockchain Ethereum. Являюсь разработчиком фреймворка Pheix, предназначенного для создания систем управления контентом с поддержкой хранения данных в blockchain.

Введение в Parity

Введение в Parity

EVM

Ethereum Virtial Machine

В сети Ethereum на каждом узле выполняется EVM. Для взаимодействия с EVM используется ethereum-клиент (коротко CLI).

Cтрого говоря, CLI запускает EVM и обеспечивает взаимодействие с ней.

Клиенты

Ethereum

Клиенты Ethereum

CLI является базовым ПО, обеспечивающим работоспособность узла в сети ethereum. Проще говоря, для запуска узла ethereum вам потребуется запустить CLI.

Parity — это мульти функциональный в смысле развертывания узла клиент, позволяющий запустить облегченный (light), архивный (archive) и полный (full) узел.

Алгоритмы консенсуса PoA

Алгоритмы консенсуса PoA

PoA — оптимальный вариант для использования в частных сетях: в сети назначаются узлы, которым делегируются права валидации блока.

В CLI Parity используется PoA алгоритм Aura, в официальном CLI geth — Clique.

Установка, настройка, тестирование

Установка, настройка и

тестирование частной PoA сети

Docker

Docker: предустановленное ПО

Наиболее простой и быстрый способ запуска частной сети ethereum - это использование docker. На узлах д.б. запущен docker-контейнер с предустановленным для выполнения CLI ПО: Go, Rust, Go-ethereum, Z3 prover, Solidity и Parity.

Docker: Do it yourself

Вы можете скачать и запустить готовый контейнер, собрать собственный контейнер, используя мой Dockerfile, или на основании инструкций из моего Dockerfile собрать все ПО вручную для своего дистрибутива linux без docker.

Адрес репозитория: https://gitlab.com/pheix-pool/docker-ethereum/container_registry

Настройка Parity узлов

Настройка Parity узлов

  • Создание файла первичной спецификации частной сети (genesis);
  • Создание файлов первичной конфигурации узлов (путь к genesis, путь к каталогу хранения данных blockchain, номера портов, настройка сети, etc…);
  • Запуск узлов с заданными конфигурационными файлами;
  • Создание аккаунтов (через REST-запросы к запущенным на предыдущем шаге узлам);
  • Дополнение спецификации частной сети данными об аккаунтах;
  • Дополнение файлов конфигурации узлов данными об аккаунтах.

Настройка Parity узлов: особенности

  • У узла parity нет этапа инициализации: путь к genesis указывается в конфигурационном файле узла и инициализация выполняется при запуске автоматически;
  • Parity умеет создавать аккаунты, адреса которых однозначно определяются некоторой фразой, т.е. при создании топологии сети можно назначить символьные имена узлам, и для этих имен parity выполнит генерацию постоянных адресов;
  • узел parity может быть запущен с единственным параметром командной строки: файлом конфигурации.

Запуск сети

Запуск PoA сети

  • Запуск узла выполняется командой parity --config <file>, при запуск узлов на удаленных серверах сопровождается некоторыми особенностями в части сетевых настроек, например, указанием IP вашего маршрутизатора;
  • Связывание узлов через REST-запрос, JS консоль или конфигруационный файл;
  • Подключение к узлу командой geth attach http://addr:port

Запуск PoA сети: helper скрипты

В репозитории https://gitlab.com/pheix-research/ethereum-local-network размещены скрипты, автоматизирующие процесс запуска частной сети:

  • patchaccounts.sh - скрипт, выполняющий все этапы настройки частной сети;
  • start.node* - скрипты запуска узлов частной сети;
  • bindpeers.sh - скрипт, выполняющий связывание узлов;
  • attach.node* - скрипты подключения JS-консоли geth;
  • reinit.sh - скрипт удаления blockchain данных из локальной файловой системы;
  • trace_tx.sh - скрипт отладки транзакции через REST-запрос.

CRUD смарт-контракт

CRUD смарт-контракт

Архитектура базы данных

Архитектура базы данных

Методы смарт-контракта

Методы смарт-контракта: ядро

  • new_table(string tabname) - создание пустой таблицы;
  • drop_table(string tabname) - удаление таблицы;
  • set(string memory tabname, uint rowid, string memory rowdata) - модификация данных по идентификатору;
  • insert(string memory tabname, string memory rowdata, uint id) - вставка данных в таблицу;
  • select(string memory tabname, uint rowid) - чтение данных по идентификатору;
  • remove(string memory tabname, uint rowid) - удаление записи по идентификатору.

Методы смарт-контракта: утилиты

  • table_exists(string tabname) - проверка существования таблицы;
  • id_exists(string tabname, uint rowid) - проверка существования записи;
  • count_tables() - подсчет количества таблиц;
  • count_rows(string tabname) - подсчет количества записей в таблице;
  • get_tabname_byindex(uint index) - получение имени таблицы по индексу;
  • get_id_byindex(string tabname, uint index) - получение идентификатора записи по индексу;
  • table_index(string tabname) - получение индекса таблицы;
  • get_max_id(string tabname) - получение максимального идентификатора для таблицы;
  • init() - инициализация тестовой базы данных.

Select All?!

Метод select_all умышленно не реализован в смарт-контракте, так как возвращаемым значение этого метода является динамический массив (действительно, изначально нам неизвестно сколько записей вернет метод). Solidity не позволяет возвращать динамические массивы по-умолчанию. Для этого нужно либо использовать pragma experimental ABIEncoderV2, либо выполнять сериализацию строк. Поэтому select_all выносится на уровень выше - CRUD-приложение верхнего уровня (node.js) реализует этот метод, используя count_tables(), get_tabname_byindex(), count_rows() и get_id_byindex().

Запуск

Репозиторий смарт-контракта

Репозиторий с рассматриваемым смарт-контрактом является публичным и доступен по адресу https://gitlab.com/pheix-research/smart-contracts

Кроме исходного текста собственно смарт-контракта в него входит набор unit-тестов и скрипт, автоматизирующий процесс компиляции смарт-контракта, а также скрипт генерирующий JS-сценарий для быстрого развертывания смарт-контракта в частной сети.

Запуск за 6 шагов

  • Клонировать репозиторий смарта-контракта в файловую систему контейнера, например в каталог /sc;
  • Сгенерировать JS-сценарий для быстрого развертывания смарт-контракта с помощью команды cd /sc/t; ./compile-contract.sh pheix_database;
  • Открыть geth консоль любого из узлов сети;
  • Выполнить развертывание смарт-контракта командой loadScript("/sс/t/pheix_database/pheix_database.js");
  • После выполнения команды (код возврата true) в geth консоли становится доступен объект storage;
  • Для инициализации тестовой БД следует выполнить команду storage.init.sendTransaction({from:eth.accounts[0],gas:4700000}).

Отладка и оценка производительности смарт-контракта

Отладка и оценка производительности смарт-контракта

Модульные тесты

Модульные тесты

Для смарт-контракта CRUD приложения был разработан набор тестов, полностью покрывающий исходный код смарта-контракта в части функций (методов). В тестах отражена специфика данных, характерных для веб-приложений. Набор тестов может быть представлен в виде двух сущностей: собственно набора модульных тестов для множества методов смарт-контракта CRUD приложения и нагрузочного теста, выполняющего сохранение в blockchain текстовых данных различного объема.

Модульные тесты

  • pheix_db_init_drop.js - тестирование init() и drop();
  • pheix_db_insert_select_set.js - тестирование new_table(), insert(), select() и set();
  • pheix_db_remove.js - тестирование remove();
  • pheix_db_select_all.js - тест реализует выборку всех данных из таблицы;
  • pheix_db_heavy_test.js - итеративный тест, в котором на каждой итерации выполняется создание нескольких таблицы, заполнение таблиц данными, удаление данных и проверка оставшихся в таблице данных.

Нагрузочный тест

Нагрузочный тест

Файлы данных и сценарии нагрузочного теста располагаются в каталоге t/pheix_database/txt. В нагрузочный тест входят:

  • convert-to-js.sh - bash сценарий, генерирующий общий js-файл (datasets.js) со всеми текстовыми данными из каталогов t/pheix_database/set_0* в виде массива строк;
  • lzw.js - реализация алгоритма Лемпеля-Зива-Велча (Lempel-Ziv-Welch) для сжатия текстовых данных перед сохранением в blockchain;
  • dataset-deploy.js - собственно сценарий нагрузочного теста.

Конфигурирование нагрузочного теста

Нагрузочный тест может быть сконфигурирован с помощью глобальных переменных:

  • _TAB_S - номер таблицы, с которой следует начать тестирование;
  • _TAB_E - номер таблицы, на которое следует закончить тестирование;
  • _GAS_CAP - увеличение газа на транзакцию в процентах от величины, измеренной функцией estimateGas().

Сжатие

Для оптимизации объемов blockchain хранилища выполняется предварительное сжатие текстовых данных с помощью алгоритма LZW (Лемпеля-Зива-Велча). Предварительное сжатие экономит до 40% объема хранилища на текстовых данных более 10кБ.

Запуск тестов

Запуск тестов

  • Сгенерировать с помощью bash сценария convert-to-js.sh файл datasets.js;
  • Установить конфигурационные переменные (по-умолчанию тест выполняется для всех таблиц, газ увеличивается на 10%: var _GAS_CAP=10;)
  • Выполнить загрузку текстовых данных loadScript("/sс/t/pheix_database/txt/datasets.js");
  • Инициализировать объект LZW, командой loadScript("/sс/t/pheix_database/txt/lzw.js"); (если нет необходимости в сжатии данных, то это шаг следует пропустить);
  • Выполнить нагрузочный текст с помощью команды loadScript("/sс/t/pheix_database/txt/dataset-deploy.js");

konstantin@narkhov.pro

https://narkhov.pro

https://gitlab.com/pheix

https://www.linkedin.com/in/knarkhov/

Learn more about creating dynamic, engaging presentations with Prezi