2 спецальная часть 2 1 Описание исходных данных 2
Скачать 1.56 Mb.
|
2.8 Разработанное основное алгоритмическое обеспечениеПрежде всего для создания блокчейн-сети необходим Python версии 3.6 и выше, с предустановленным менеджером пакетом pip (рисунок 2.14), микрофреймфорк Flask для дальнейшей интеграции блокчейн-сети с вебсайтом, а также HTTP-клиент, такой как Postman. Рисунок 2.14 – Установка микрофреймфорка Flask В IDE создадим файл с именем blockchain.py. Основная часть кода блокчейн-сети будет находится именном в этом файле. Создадим класс Blockchain (рисунок 2.15), конструктор которого создает начальный пустой список для хранения нашего блокчейна и другой класс для хранения транзакций. Структура нашего класса Рисунок 2.15 – Структура класса Blockchain Наш класс blockchain отвечает за управление цепочкой. Он будет хранить транзакции и иметь несколько вспомогательных методов для добавления новых блоков в цепочку. Давайте опишем некоторые методы. Как выглядит блок? Каждый блок имеет индекс, временную метку, список транзакций, подтверждение и хеш предыдущего блока (рисунок 2.16). Вот пример того, как выглядит один блок: Рисунок 2.16 – Блок данных На этом этапе идея цепочки должна быть очевидной – каждый новый блок содержит в себе хеш предыдущего блока. Это очень важно, потому что именно это дает неизменность цепочки блоков: если злоумышленник повредил более ранний блок в цепочке, то все последующие блоки будут содержать неправильные хеши. Добавление транзакций в блок: 50 Нам понадобится способ добавления транзакций в блок. Наш метод new_transaction () как раз за это отвечает, и он довольно прост (рисунок 3.9): Рисунок 2.17 – Метод добавления транзакций в блок После того, как new_transaction () добавляет транзакцию в список, она возвращает индекс блока, в который будет добавлена транзакция – следующий, который будет добыт. Это будет полезно позже пользователю, отправляющему транзакцию. Создание новых блоков: Когда будет создан наш блокчейн, нам нужно заполнить его генезисным блоком – блоком без предшественников, являющимся фундаментом для остальной цепи. Генезисный блок является фундаментом для остальной цепи, это очень важный элемент любого блокчейна. В генезисном блоке может быть записана информация о том, когда и какой блокчейн создан, с какими параметрами, указаны валидаторы и кандидаты в валидаторы, сколько монет будет зачислено на какие адреса на определенной высоте блока. Нам также нужно добавить «доказательство» в наш блок генезиса, которое является результатом майнинга (или доказательства работы). Помимо создания блока genesis в нашем конструкторе (рисунок 2.18), также уточняем методы для new_block (), new_transaction () и hash (): Рисунок 2.18 – Методы создания нового блока Выше мы описали общее представление нашего блокчейна. Далее опишем, как новые блоки создаются, подделываются или добываются. Понимание доказательства работы: 52 Алгоритм Proof of Work (PoW) – это то, как новые блоки создаются или добываются в цепочке блоков. Цель PoW - найти число, которое решает проблему. Это число должно быть трудно найти, но его легко проверить – говоря вычислительным путем - любому, кто находится в сети. Это основная идея Proof of Work. Рассмотрим простой пример. Давайте решим, что хеш некоторого целого числа x, умноженного на другой y, должен заканчиваться на 0. Итак, hash (x * y) = ac23dc...0. И для этого упрощенного примера давайте предположим, что x = 5. Реализация этого в Python (рисунок 2.19) Рисунок 2.19 – Упрощенный пример алгоритма PoW в Python Решение здесь: y = 21. Так как полученный хеш заканчивается 0: hash (5 * 21) = 1253e9373e...5e3600155e860 В биткойнах алгоритм Proof of Work называется Hashcash [20] – алгоритм доказательства правильности работы, требующий выборочного объёма данных для вычислений, но при этом доказательство может быть эффективно подтверждено. Данный алгоритм используется в основном с целью уменьшенить количество спама и DoS-атак. Нам же алгоритм Hashcash необходим в первую очередь для создания нового блока. Сложность алгоритма определяется количеством символов, которые ищут в строке. Далее реализуем базовый алгоритм Proof of Work (рисунок 2.20) для нашей блокчейн-сети. Задача будет следующая: найти число p, которое при 53 хешировании с решением предыдущего блока создает хеш с 4 ведущими нулями. Рисунок 2.20 – Алгоритм «Proof to Work» Для настройки сложности алгоритма, мы можем изменить количество ведущих нулей. Но 4 достаточно. Ибо добавление даже одного начального нуля сильно увеличит время работы алгоритма. Наш класс почти завершен, и мы готовы начать взаимодействовать с ним с помощью HTTP-запросов. Следующим шагом будет представление нашей блокчейн-сети как API. Мы собираемся использовать Python Flask Framework [21]. Это микрофреймворк, позволяющий легко сопоставлять конечные точки с функциями Python. Это позволяет нам общаться с нашей цепочкой блоков через интернет, используя HTTP-запросы. Мы создадим три метода. 1. /transactions/new для создания новой транзакции в блоке 2. /mine чтобы сообщить нашему серверу, чтобы мой новый блок. 3. /chain чтобы вернуть полный блокчейн. Настройка Flask (рисунок 2.21): Наш «сервер» сформирует единый узел в нашей сети блокчейн. Создадим некоторый шаблонный код: Рисунок 2.21 – Настройка Flask Краткое объяснение того, что сделано выше: 1) создали экземпляр нашего узла; 2) сгенерировали случайное имя для нашего узла; 3) создали экземпляр нашего класса Blockchain; 4) определили конечную точку /mine, которая является запросом GET; 5) определили конечную точку /transactions/new, которая является запросом POST, поскольку мы будем отправлять на нее данные; 6) определили конечную точку /chain, которая возвращает полный блокчейн; 7) запустили сервер через порт 5000. Конечная точка транзакций: Вот так будет выглядеть запрос на транзакцию (то, что пользователь отправляет на сервер) (рисунок 2.22): Рисунок 2.22 – Вид запроса на транзакцию Так как у нас уже есть наш метод класса для добавления транзакций в блок, остается лишь написать функцию (рисунок 2.23) для добавления транзакций: Рисунок 2.23 – Добавление транзакции Конечная точка майнинга: Наша конечная точка майнинга – это то место, где происходит основная задача блокчейна. 1. Рассчитывается доказательство работы (Proof to Work) (рисунок 2.24). 2. Генерируется новый блок и добавляется в цепочку. Рисунок 2.24 – Proof to Work, генерация и добавление блока в цепочку Стоит обратить внимание, что получателем добытого блока является адрес нашего узла. И большая часть того, что мы сделали здесь, это просто взаимодействие с методами нашего класса Blockchain. На этом мы закончили и можем начать взаимодействовать с нашей цепочкой блоков. Взаимодействие с нашей цепочкой блоков: Используем Postman [22] для взаимодействия с нашим API по сети. Запустим сервер: $ python blockchain.py * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) 57 Попробуем добыть блок, отправив запрос GET (рисунок 2.25) на http://localhost:5000/mine: Рисунок 2.25 – Попытка «добычи» блока запросом GET Создадим новую транзакцию, сделав POST-запрос (рисунок 2.26) к http://localhost:5000/transactions/new с телом, содержащим нашу структуру транзакции: Рисунок 2.26 – Попытка создания транзакции После перезапуска сервера были «добыты» ещё два блока, чтобы получить в итоге 3 блока. Далее проверим всю цепочку (рисунок 2.27), запросив http://localhost:5000/chain Рисунок 2.27 – Проверка цепи |