Блокчейн: организация сети, проверка подписи и задание для студента, часть 2

Предисловие


В первой части было рассказано про возможности блокчейна, структуру и ЭЦП, в этой части будет рассказано про: проверку подписи, майнинг и примерную организацию сети. Отмечу, что не являюсь специалистом по распределенным системам (организация сети может быть не верной).

Одноранговая сеть (P2P)


Одноранговая (равноправная) сеть — это сеть, основанная на равноправии участников. Часто в такой сети отсутствуют выделенные серверы, а каждый узел (peer) является как клиентом, так и выполняет функции сервера. В отличие от архитектуры клиент-сервера, такая организация позволяет сохранять работоспособность сети при любом количестве и любом сочетании доступных узлов. Участники сети называются пиры.

Организация сети


Сперва необходимо ответить на вопросы:

  • как клиенты узнают о том, что существуют другие клиенты?
  • каким образом гарантировать оптимальное взаимодействие между клиентами, если их могут отделять друг от друга континенты?


Каждый клиент, участвующий в работе сетевого приложения P2P, для преодоления этих проблем должен быть способен выполнять следующие операции:

  • обнаруживать других клиентов;
  • подключаться к другим клиентам;
  • взаимодействовать с другими клиентами.


При подключении новый клиент связывается с трекером, который содержит списки подключенных узлов. Таких трекеров может быть много, они нужны для оптимальной связи между клиентами, под оптимальностью понимается, что скачивать цепочку блоков лучше с узла, который географически расположен рядом, чем тот, который дальше. То есть связующий центр позволяет узнать новому клиенту, кто уже есть в сети и предоставляет список наиболее «подходящих» узлов. Пример сети продемонстрирован на рисунке 1.
apm7v6r_n6jrd9mxuis905gwkfu.png
Рисунок 1 — децентрализованная сеть с трекерами, содержащими списки подключенных узлов

Майнинг


В зависимости от типа блокчейна (децентрализованный вариант с использованием доказательства работы или централизованный с доверенным центром) блоки транзакций (пустые) могут создаваться майнерами или главным узлом (центром). Майнеры — узлы сети, которые вычисляют новый блок (имеется ввиду блок транзакции). Что значит вычислить новый блок и почему его надо вычислять? Все дело в том, что в некоторых типах блокчейна создать новый блок не так просто, необходимо решить сложную задачу путем перебора чисел/фразы (если быть точным получить хэш с 10 нулями в начале ~ 0000000000HD83HA653JA…83JS), это сделано с целью безопасности, чтобы другие участники не смогли быстро подменить цепочку блоков, т.к. на расчет такого хэша могут уйти часы, дни, недели (подменив один, придется пересчитать другие блоки). В других типах блокчейна эти хэши уже могут быть вычислены заранее и соответственно отпадает необходимость в майнерах, как добытчиках блоков, здесь цель майнера уже не добывать блок, а предоставлять свой жесткий диск для хранения цепочки.

Проверка данных блокчейна


После добавления нового блока или вставки новых данных в список транзакций уже созданного блока, необходимо, чтобы другие участники сети проверили данную информацию.
dlyamqmhkbhujjaxfrdymxjgmks.png

Алгоритм проверки блока


Проверка нового блока делится на этапы:

  1. Берется адрес последнего принятого блока (текущий блок еще не принят и не является последним) и список транзакций текущего блока. Затем вычисляется хэш:
  2. Полученный хэш сравнивается с хэешем (связующим) еще не принятого блока. Если совпали, тогда блок корректный и добавляется к себе в цепочку. Иначе, данные некорректные и блок не принимается.

Пример проверки подписи на языке C#


Передаем методу полученные из транзакции: данные, подпись и адрес блока (публичный ключ).

private static bool VerifyMessage(string originalData, string signedDataBase64, string publicKey)
{
    // результат проверки будет записан в это поле
    bool verified;

    // Получаем объект класса RSA через провайдер
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048);

    // Говорим, что у нас уже есть приватный ключ (например взятый из файла)  
    // и следует использовать его
    rsa.FromXmlString(publicKey);

    // Преобразуем символы строки в последовательность байтов   
    byte[] originalByteData = Encoding.UTF8.GetBytes(originalData);

    // Конвертация подписи из string в кодировке Base64 в массив байт
    byte[] signedData = Convert.FromBase64String(signedDataBase64);

    // данные originalByteDate хэшируются алгоритмом SHA512, полученный хэш сравнивает с signedData
    // результат сравнения возвращается в verified
    verified = rsa.VerifyData(originalByteData, CryptoConfig.MapNameToOID("SHA512"), signedData);
        
    return verified;
}

Задание


Необходимо расширить ПС из первой части, реализовав децентрализованную сеть с трекерами. Узлы должны уметь взаимодействовать между собой (передавать/получать/проверять информацию). Трекеры — обновлять/отдавать список узлов.
Функции трекер-узла:

  1. Регистрация (добавление в список) клиента при подключении к трекеру;
  2. Возвращение списка подключенных узлов.


Функции клиента:

  1. Подключение к трекер-узлу и узлам сети из списка, полученного от трекера;
  2. При подключении к узлам сети синхронизировать историю транзакций, приняв ее от другого участника;
  3. При добавлении нового блока или транзакции — анонсировать (передать) остальным участникам;
  4. Получение нового блока или транзакции от других участников;
  5. При получении нового блока или транзакции от других участников, необходимо их проверить и принять решении о вставке в свою цепочку или отклонить.

Источники


  1. ProfessorWeb // Сеть P2P
  2. StackOverFlow // Programming P2P application

© Habrahabr.ru