Ключевые концепции этой новаторской технологии и способы ее создания
Какие?
В этой статье мы проанализируем ключевые концепции технологии блокчейн. Вместе мы рассмотрим внутреннюю работу блокчейна и узнаем, как информация может быть публично храниться в распределенной сети серверов.
Как?
Все это будет сделано путем создания простого блокчейна с нуля. Мы пройдем основные этапы создания блокчейна, и я добавлю несколько фрагментов кода, которые помогут вам следовать вместе с языком программирования Python. Тем не менее, каждый шаг будет хорошо документирован, так что вы можете следовать на любом удобном для вас языке.
Исходный код, использованный в этой статье, можно найти по адресу: https://github.com/jzsiggy/blockchain-from-scratch
Глава 1. В чем суть блокчейна?
Блокчейны становятся все более популярными на сегодняшних рынках. Сервисы, которые предоставляют технологию блокчейн, уже разрабатываются Amazon, Microsoft, Google и другими крупными компаниями. Многие люди часто связывают блокчейн с криптовалютами, такими как биткойн, но во многих случаях это не так.
Прямо сейчас вы можете спросить себя, почему блокчейн привлекает такое внимание. Подумаешь?
Итак, дело в том, что блокчейны позволяют нам создавать безопасные, общедоступные и децентрализованные «базы данных» для хранения любого типа информации. До появления блокчейна большие объемы данных должны были храниться и проверяться каким-либо посредником или посредником.
В случае финансовых данных посредниками являются банки. Мы рассчитываем на то, что банки отслеживают все наши финансовые данные, и надеемся, что они не будут вмешиваться в наши данные или каким-либо образом к ним обращаться. Этот метод работает, однако дает этим учреждениям большую власть.
Основная идея технологии блокчейн заключается в использовании криптографии и сложных компьютерных алгоритмов для создания безопасного и прозрачного метода исключения этих посредников, позволяющего хранить и проверять данные в огромной открытой сети серверов.
Давайте погрузимся, и мы поймем, как это сделать!
Глава 2: Как хранятся данные?
А что за блок?
Прежде чем мы начнем, позвольте мне быстро объяснить хэш-функции. Они очень, очень, очень важны для работы нашего блокчейна!
Хеш-функция - это функция, которая принимает в качестве входных данных строку любой длины и возвращает строку фиксированной длины, которая выглядит очень случайной, но это не так. Каждая строка имеет собственный выходной хэш, который всегда один и тот же.
Вот как выглядит хеш строки «Hello world»:
Важно отметить, что даже незначительное изменение строки ввода полностью изменит вывод. Например:
Все в порядке! А теперь приступим!
Что в блоке?
Один блок в цепочке блоков хранит записанные в него данные, хэш предыдущего блока и собственный хэш.
Изменить данные после их записи в блок действительно сложно, потому что каждый блок, записанный в цепочку блоков, ссылается на хэш своего предыдущего блока. Таким образом, даже если вы слегка измените блок, его хэш полностью изменится, и поэтому следующий блок также должен будет измениться - потому что он должен иметь хэш предыдущего блока - и так далее для следующих блоков. Если вы изменяете какой-либо блок блокчейна, вы должны переписать всю цепочку.
Когда мы преобразуем эту логику в код, в Python структура данных блока выглядит примерно так (до сих пор):
В конструкторе нашего класса Block мы создаем экземпляр данных, вставленных в блок, хэш предыдущего блока, и мы применяем хеш-функцию к нашему собственному блоку и сохраняем вывод в хеш-переменной.
Давайте также создадим метод to_string, который возвращает строку, содержащую данные и хэш предыдущего блока.
Это означает, что мы можем создать структуру данных блока, запустив:
Прежде чем мы продолжим, позвольте мне просто указать, что у каждой цепочки блоков должен быть начальный блок, верно? Блок, у которого нет предыдущего. Этот блок называется Genesis Block и обычно указывает на нулевой хеш в качестве своего предыдущего блока.
Глава 3: Доказательство работы
и почему так сложно переписать блокчейн
В предыдущей главе мы поняли, что для изменения данных в одном блоке мы должны переписать всю цепочку блоков с того места, где мы изменили блок. Вы могли спросить, что делает процесс перезаписи всей цепочки блоков таким сложным, поскольку здесь нет сложных и трудоемких операций.
В этой главе мы подробно рассмотрим некоторые другие требования, которые должен соблюдать блок, что затрудняет создание блоков.
Прежде чем мы начнем, давайте вернемся к нашим хэш-функциям.
У этих функций есть еще одна важная характеристика, о которой я еще не упомянул, а именно: Эти функции невозможно вычислить в обратном направлении.
Это означает, что, хотя для компьютера очень просто сгенерировать хеш из входной строки, невероятно сложно найти «генераторную строку», просто зная выходные данные. Фактически, нет лучшего способа найти входную строку, кроме как угадать строку и проверить, является ли выходной хеш ожидаемым. В среднем, чтобы найти входную строку, удовлетворяющую желаемому хешу, потребуется 2 предположения, что является просто неописуемо огромным количеством предположений даже для компьютера.
Чтобы злоумышленник не мог изменить блок и быстро переписать всю цепочку блоков, для успешного создания блока его хэш должен подчиняться простому правилу: он должен начинаться с определенного количества нулей (количество нулей может меняться в зависимости от сложность, которую мы хотим связать с созданием нового блока).
Например, предположим, что мы определяем, что для того, чтобы блок был действительным в нашей цепочке блоков, он должен начинаться с 4 нулей. Теперь, каждый раз, когда мы хотим добавить новый блок в нашу цепочку блоков, мы должны применить к нему хеш-функцию и посмотреть, начинается ли выходной хэш с 4 нулей. Если этого не произошло, мы должны немного изменить наш блок и повторить попытку. Эта процедура повторяется до тех пор, пока блок не станет действительным.
Это фундаментальная концепция, лежащая в основе Proof of Work, и почему блоки так сложно создавать. Если задуматься, это правило подразумевает, что для создания нового блока потребуется много времени, энергии и вычислительной мощности.
Это также означает, что мы должны добавить другую информацию при хешировании нашего блока: число, которое меняется каждый раз, когда мы делаем предположение. Это необходимо для того, чтобы входная строка при каждом предположении немного отличалась, поэтому каждый раз у нас будет другой хэш. Это число называется Nonce.
Добыча полезных ископаемых
Прежде чем мы перейдем к коду, давайте проверим последнюю фундаментальную часть теории, чтобы собрать воедино нашу цепочку блоков: майнинг блоков.
Если вы когда-либо раньше читали подробную статью о блокчейне, этот термин наверняка приходил вам в голову.
В сети блокчейнов серверы, которые разрушают эти сложные в вычислительном отношении алгоритмы для создания новых блоков, называются майнерами. Часто в больших блокчейнах эти майнеры представляют собой очень большие склады, заполненные серверами, которые работают круглосуточно и без выходных, уничтожая эти алгоритмы, чтобы обеспечить развитие блокчейна.
Это все, что касается теории в этой главе! Теперь вернемся к нашему коду и исправим наш класс Block, чтобы его хэш подчинялся правилам нашей цепочки блоков и начинался с определенного количества нулей.
Мы добавим новый метод в наш класс Block под названием calculate_valid_hash. В этом методе мы инициализируем переменную hash пустой строкой, а значение nonce равным 0. Пока хеш не утвержден методом is_hash_valid, мы увеличим одноразовый номер и попробуйте еще раз. Когда мы находим одноразовое значение, которое при хешировании с данными блока одобряется нашим методом is_hash_valid, мы прекращаем цикл и устанавливаем хэш блока равным вычисленному нами значению.
Мы добавим этот новый метод в наш конструктор.
С этими модификациями каждый раз, когда мы создаем экземпляр нового блока, нам придется проходить процесс создания доказательства работы для майнинга блока.
Пришло время создать новый класс: Блокчейн.
Как только мы создадим экземпляр класса Blockchain, мы инициализируем атрибут blocks пустым массивом. Для этого мы добавим в конструктор следующую строку кода.
Теперь давайте добавим метод в наш класс блокчейна для создания Genesis Block! Этот метод будет вызываться в конструкторе нашей цепочки блоков.
Для этого мы должны создать метод set_genesis_block и инициализировать переменную data как «Genesis» (или как вам угодно). Мы также инициализируем переменную prev_hash строкой из 64 нулей. Теперь мы создадим экземпляр блока из этих данных и добавим его в качестве первого блока нашей цепочки блоков. Мы можем гарантировать, что этот блок будет иметь допустимый хэш благодаря методу calculate_valid_hash в конструкторе нашего класса Block.
Наконец, чтобы закончить нашу цепочку блоков, давайте добавим метод добавления блока в нашу цепочку блоков. Этот метод будет получать только данные, которые входят в блок. Затем он получит хэш последнего блока и создаст новый блок из предыдущего хеша и данных. Как и в случае с блоком Genesis, мы можем гарантировать, что хеш нового блока будет действительным, благодаря методу calculate_valid_hash. Наконец, мы добавим недавно добытый блок в наш массив blocks.
Теперь, когда нам удалось создать всю структуру блокчейна, мы можем инициализировать его следующим образом!
Я создал дополнительный метод в классе Blockchain под названием get_blocks, который возвращает список со всеми блоками. Нам может быть интересно отладить, протестировать и визуализировать нашу цепочку блоков.
Когда мы запускаем этот код в нашем терминале или в командной строке, мы получаем следующий результат:
Если мы проанализируем все хэши блоков в нашей цепочке блоков, мы поймем, что все они начинаются с трех нулей! Это доказывает нам, что блок действительно является действительным блоком, и что наша машина должна была проделать некоторую работу, чтобы добыть блок.
Хэш блока в блокчейне Биткойн выглядит примерно так:
Полный код нашего класса Block теперь выглядит примерно так:
И полный код нашего класса Blockchain будет выглядеть так:
Вот и код! В следующей главе я объясню, как можно улучшить эту реализацию и распределить блокчейн по сети узлов!
Глава 4: Улучшение нашей реализации
Нам удалось создать полноценный блокчейн с нуля и запустить его в кратчайшие сроки, но он все еще не децентрализован и состоит из множества узлов.
Преобразование нашей реализации блокчейна в децентрализованную было бы немного сложнее, поэтому я оставлю это для другой статьи, а пока мы можем обсудить некоторые другие факторы, которые необходимо принять во внимание.
На данный момент наш компьютер - единственный узел, работающий в этой цепочке блоков. Все данные поступают с нашей машины, когда мы вызываем метод add_new_block, и наш процессор также выполняет всю добычу блоков.
В распределенной цепочке блоков у нас были бы определенные узлы, выполняющие майнинг. Эти узлы будут прослушивать новые данные или транзакции, транслируемые в сети, и будут продолжать попытки найти значение nonce, которое делает блок действительным. Когда майнер находит это значение nonce, он транслирует новый блок в сеть. Все остальные узлы в сети могут легко проверить, действителен ли блок, потому что все, что им нужно сделать, это применить хеш-функцию к блоку с заданным одноразовым номером. Если блок начинается с X нулей, блок действителен.
Ключевое правило нашей распределенной цепочки блоков состоит в том, что если узел получает два конфликтующих блока и оба имеют действительные хэши, он должен доверять блоку с самой длинной историей.
Это означает, что если мы хотим вставить блок с мошеннической информацией в нашу цепочку блоков, мы не только должны добывать мошеннический блок до того, как сеть добывает аутентичный блок, но мы должны продолжать добычу блоков в нашей мошеннической цепочке блоков навсегда.
Имея это в виду, мы можем утверждать, что единственный способ мошенничества с блокчейном - владение более чем половиной сети. Только в том случае, если вам принадлежит более половины сети, у вас будет вычислительная мощность, необходимая для вставки мошеннического блока в цепочку и продолжения цепочки оттуда.
В крупных надежных блокчейнах, таких как блокчейн Биткойн или Эфириум, владение более чем половиной сети практически невозможно, поэтому мы можем гарантировать безопасность блокчейна.
Заключение
К настоящему времени мы поняли, как работают блокчейны и почему они так важны. Мы создали нашу собственную функциональную цепочку блоков, которая может хранить данные в блоках и добывать блоки с помощью доказательства работы.
Код для этой статьи можно найти по адресу: https://github.com/jzsiggy/blockchain-from-scratch
Не стесняйтесь клонировать, разветвлять или копировать код. Также приветствуются запросы на вытягивание, если у вас есть предложения!
Я надеюсь, что эта статья могла помочь или вдохновить вас каким-либо образом! 😁😁😁
использованная литература
Фрагменты кода, созданные с помощью Carbon - https://carbon.now.sh/