Читать книгу «Введение в технологию Блокчейн» онлайн полностью📖 — Тимура Машнина — MyBook.
image

Блоки Bitcoin

До сих пор мы рассматривали, как создаются и потребляются отдельные транзакции.

Но, как мы видели раньше, транзакции сгруппированы в блоки.

Зачем это нужно?

В принципе, это ничто иное как оптимизация.

Если бы майнеры должны были бы приходить к консенсусу по каждой транзакции отдельно, скорость, с которой новые транзакции принимались бы системой, была бы намного ниже.

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

Это позволяет повысить эффективность проверки структуры цепочки блоков.

Каждый блок должен включать одну или несколько транзакций.

Первая из этих транзакций должна быть транзакцией coinbase или транзакцией генерации, которая собирает и тратит вознаграждение за блок, состоящее из вознаграждения за сам блок и любых транзакционных сборов, оплаченных транзакциями, включенными в этот блок.

Цепочка блоков – это умная комбинация двух разных структур данных на основе хэшей.


Первая структура – это хеш-цепочка блоков.

Каждый блок имеет заголовок блока с хэш-указателем на транзакции и хэш-указателем на предыдущий блок в последовательности.

Вторая структура данных – это дерево всех транзакций для каждого блока, которые включены в этот блок.

Все транзакции, включая транзакцию coinbase, кодируются в блоке в бинарном формате.

Этот формат хэшируется для создания идентификатора транзакции.

Из этих идентификаторов строится дерево merkle путем спаривания каждого идентификатора с одним другим идентификатором и последующим их объединением.

Если существует нечетное число идентификаторов, идентификатор без партнера хешируется с копией самого себя.

Затем результирующие хеши объединяются по парам и хэшируются вместе.

Любой хеш без партнера хэшируется сам с собой.

Процесс повторяется до тех пор, пока не останется только один хеш, или корень merkle.

Таким образом, это дерево Merkle позволяет нам иметь дайджест всех транзакций в блоке эффективным образом.

Как мы видели ранее, чтобы доказать, что транзакция включена в конкретный блок, мы можем предоставить путь через дерево, длина которого – это логарифм числа транзакций в блоке.

Для повторения, блок состоит из заголовка с данными, за которыми следует список транзакций, расположенных в древовидной структуре.

Заголовок блока содержит информацию, связанную с майнингом.



Вспомните, что хеш заголовка блока должен начинаться с большого количества нулей для того, чтобы блок был действительным.

Доказательство работы подразумевает, что хэш заголовка блока должен быть меньше указанного.

Другой способ сказать это, что хэш заголовка блока должен начинаться с определенного количества нулей.

Любой блок, заголовок которого не создает хэш, который меньше целевого значения, будет отклонен сетью.

Целевое значение настраивается каждые две недели, чтобы поддерживать среднее время создания нового блока 10 минут.

Заголовок также содержит значение «nonce», которое изменяется майнером, чтобы хэш заголовка блока был меньше целевого значения.

Заголовок содержит отметку времени и целевое значение, которое определяет трудность нахождения этого блока.

Таким образом, если после того, как вы обработали каждую транзакцию и нашли корень дерева Merkle, добавили его в заголовок блока с хешем предыдущего блока и nonce, хэшировали заголовок и создали значение, которое с правильным количеством нулей не попадает в указанный целевым значением диапазон, тогда изменяется значение nonce, заголовок блока снова хэшируется и так до тех пор, пока хэш заголовка блока не будет меньше целевого значения.

Заголовок – это единственное, что хэшируется во время майнинга.

Чтобы проверить цепочку блоков, нам нужно только посмотреть на заголовки.

Единственными данными транзакций, включенными в заголовок, является корень дерева транзакций – поле «mrkl_root».



Как я уже сказал, блок содержит специальную транзакцию в дереве Merkle, называемую транзакцией «coinbase».

Здесь происходит создание новых монет в Биткойне.

Эта транзакция выглядит как обычная транзакция, но имеет несколько отличий:

Она всегда имеет один вход и один выход, при этом вход не тратит предыдущий выход и, следовательно, содержит нулевой хэш указатель, так как он чеканит новые биткойны и не тратит существующие монеты.

Также стоимость выхода в настоящее время составляет около 6,25 биткойнов.

Выходное значение – это доход майнера от блока.

Оно состоит из двух компонентов: награды за добычу блока, которая устанавливается системой, и которая делится пополам каждые 210 000 блоков (около 4 лет) и комиссионных сборов, взимаемых с каждой транзакции, включенной в блок.

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

Известно, что в самом первом блоке, добытом в Биткойне, параметр coinbase ссылался на историю в газете Times of London, в которой участвовал канцлер, спасающий банки.

Это интерпретировалось как политический комментарий о мотивации для запуска биткойн.

Это также служит доказательством того, что первый блок был добыт после того, как газета вышла 3 января 2009 года.

Также параметр coinbase может использоваться для уведомления майнерами о поддержке различных новых функций.

Чтобы лучше понять формат блока и формат транзакции, лучше всего изучить цепочку блоков.

Есть много веб-сайтов, которые делают эти данные доступными, например, blockchain.info.



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

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

Сеть Bitcoin

До сих пор мы говорили о способности участников публиковать транзакцию и вводить ее в цепочку блоков, как будто это происходит по волшебству.

На самом деле это происходит с помощью сети Биткойн.


Это одноранговая сеть, и она наследует многие идеи одноранговых сетей.

В сети Bitcoin все узлы равны.

Здесь нет иерархии, и нет особых узлов или главных узлов.

Эта сеть работает через протокол TCP и имеет случайную топологию, где каждый узел связан с другими случайными узлами.

Новые узлы могут присоединиться в любое время.

Фактически, сегодня вы можете скачать клиент Bitcoin, развернуть свой компьютер в качестве узла, и он будет иметь равные права и возможности, как и любой другой узел в сети Bitcoin.

Сеть меняется со временем и очень динамична из-за входа и выхода узлов.

Не существует явного способа покинуть сеть.

Вместо этого, если узел не был слышен некоторое время – три часа – это длительность, которая жестко закодирована в большинстве клиентах – другие узлы начинают забывать этот узел.

Таким образом, сеть обрабатывает узлы, переходящие в офлайн режим.

Напомним, что узлы соединяются со случайными одноранговыми узлами и нет никакой географической топологии.

Теперь предположим, что вы запустили новый узел и хотите присоединиться к сети.

Вы начинаете с простого сообщения для одного узла, о котором вы знаете.

Обычно он называется вашим семенным узлом seed node, и есть несколько разных способов поиска списков семенных узлов, к которым можно подключиться.

Вы отправляете специальное сообщение «Скажите мне адреса всех других узлов в сети, о которых вы знаете».

Вы можете повторить процесс с новыми узлами, о которых вы узнаете, столько раз, сколько хотите.

Затем вы можете выбрать, к каким из них следует подключиться, и вы станете полнофункциональным членом сети Bitcoin.

Существует несколько шагов, которые используют случайность, и результатом является то, что вы получаете случайный набор узлов.

Чтобы присоединиться к сети, все, что вам нужно знать, – это связаться с одним узлом, который уже находится в сети.

Для чего нужна сеть?

Конечно, чтобы поддерживать цепочку блоков.

Чтобы опубликовать транзакцию, мы хотим, чтобы об этом узнала вся сеть.



Это происходит с помощью простого алгоритма наводнения, иногда называемого протоколом сплетен.

Если Алиса хочет заплатить Бобу, ее клиент создает, и ее узел отправляет эту транзакцию ко всем узлам, с которыми она связана.

Каждый из этих узлов выполняет серию проверок, чтобы определить, принять и транслировать или нет дальше эту транзакцию.

Если проверки проходят успешно, узел, в свою очередь, отправляет транзакцию всем своим узлам-пирам.

Узлы, которые принимают эту транзакцию, помещают ее в пул транзакций, о которых они слышали, но которые еще не находятся в цепочке блоков.

Если узел получает транзакцию, которая уже находится в пуле, он больше не транслирует ее.

Это гарантирует, что протокол наводнения прекратится, и транзакции не будут циклически перемещаться по сети вечно.

Помните, что каждая транзакция однозначно определяется своим хешем, поэтому ее легко найти в пуле.

Теперь вопрос, когда узлы узнают о новой транзакции, как они решают, должны ли они ретранслировать ее?

Для этого существуют четыре проверки.

Первая и самая важная проверка – проверка транзакции – транзакция должна быть валидной для текущей цепочке блоков.

Узлы запускают скрипт для каждого предыдущего выхода, который тратится, и проверяют, чтобы скрипт вернул true.

Во-вторых, они проверяют, чтобы выходы, потраченные в этой транзакции, еще не были потрачены.

В-третьих, они не будут передавать уже полученную ранее транзакцию.

В-четвертых, по умолчанию, узлы будут принимать и ретранслировать «стандартные» скрипты на основе небольшого белого списка скриптов.

Все эти проверки – это просто проверки на основе здравомыслия.

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

Так как это одноранговая сеть, и может присоединиться любой узел, всегда существует вероятность того, что какой-то узел будет транслировать двойные траты, нестандартные транзакции или совершенно недействительные транзакции.

Вот почему, желательно, чтобы каждый узел выполнял эти проверки.

Так как в сети существует латентность, возможно, что узлы будут иметь разные пулы ожидающих включение в блокчейн транзакций.

Это становится особенно интересным и важным, когда есть попытка двойной траты.

Предположим, что Алиса пытается заплатит один и тот же биткойн как Бобу, так и Чарли, и отправляет две транзакции примерно в одно и то же время.

Некоторые узлы сначала услышат о транзакции Алиса → Боб, а другие сначала услышат о транзакции Alice → Charlie.

Когда узел слышит любую из этих транзакций, он добавляет ее в свой пул транзакций, и, если он услышит о другой транзакции позже, это будет выглядеть как двойная трата.

Узел откажется от последней транзакции и не будет ретранслировать ее или добавлять ее в пул транзакций.

В результате временно между узлами возникнет разногласие о том, какие транзакции следует поместить в следующий блок.

Это называется созданием условия гонки.

Хорошей новостью является то, что все будет в порядке.

Тот, кто замайнит следующий блок, по существу разорвет эту связь и решит, какая из этих двух ожидающих транзакций должна быть окончательно помещена в блок.

Скажем, транзакция Алисы → Чарли попадает в блок.

Когда узлы с транзакцией Алиса → Боб услышат об этом блоке, они выведут эту транзакцию из своих пулов ожидающих транзакций, потому что это двойная трата.

Также, когда узлы с транзакцией Alice → Charlie услышат об этом блоке, они выведут и эту транзакцию из своих пулов, потому что она уже попала в цепочку блоков.

Так что больше не будет никакого разногласия, когда этот блок распространится в сеть.

Так как поведение по умолчанию заключается в том, что узлы должны принимать во внимание то, что они слышат в первую очередь, имеет значение местоположение узлов в сети.

Если две конфликтующие транзакции или блока будут объявлены в двух разных позициях в сети, оба они начнут распространяться по всей сети и какая транзакция узла будет услышана первой, будет зависеть от того, где этот узел находится в сети.

Конечно, это предполагает, что каждый узел реализует эту логику, согласно которой узлы сохраняют все, что они слышат в первую очередь.

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

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

До сих пор мы в основном обсуждали распространение транзакций.

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

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

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

Проверка блока является более сложной, чем проверка транзакций.

В дополнение к проверке заголовка и того, что значение хеша заголовка находится в допустимом диапазоне, узлы должны проверять каждую транзакцию, включенную в блок.

Наконец, узел будет ретранслировать блок только в том случае, если он основывается на самой длинной ветви цепочки блоков.

Это позволяет избежать образования вилок.

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

Это создаст вилку, но все будет в порядке, потому что протокол биткойна разработан таким образом, чтобы противостоять этому.

Теперь вопрос, какова латентность алгоритма наводнения или сплетен?



График на слайде показывает среднее время, за которое новые блоки распространяются в каждый узел сети.

Три линии показывают время покрытия блоком 25, 50 и 75 процентов сети.

Как вы можете видеть, время распространения пропорционально размеру блока.

Это связано с тем, что пропускная способность сети является узким местом.

Большие блоки занимают более 30 секунд для распространения на большинство узлов в сети.

Таким образом, это не очень эффективный протокол.

В Интернете 30 секунд довольно долгое время.

В дизайне Биткойна наличие простой сети с простой структурой, где узлы равны и могут приходить и уходить в любое время, имеют приоритет над эффективностью.

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

Если бы сеть была разработана сверху вниз для повышения эффективности, тогда путь между любыми двумя узлами был бы коротким.

Теперь вопрос, какой размер сети биткойнов.

Трудно измерить, насколько велика сеть, так как она динамична, и не существует центрального узла.

Ряд исследователей дают разные оценки.

Некоторые говорят, что более миллиона IP-адресов действуют одновременно, как узлы биткойна.

С другой стороны, оценивают, что в сети находятся только от 5000 до 10000 узлов, которые постоянно подключены и полностью проверяют каждую транзакцию, которую они слышат.

Полностью проверяющие узлы должны быть постоянно подключены, чтобы слышать обо всех данных.

Чем дольше узел находится в автономном режиме, тем ему дольше придется восстанавливать актуальность данных, когда он снова присоединиться к сети.

Такие узлы должны хранить полную цепочку блоков и нуждаются в хорошем сетевом соединении, чтобы иметь возможность слышать каждую новую транзакцию и пересылать ее пирам.

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

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

На сегодняшний день, в блочной цепочке насчитывается около 300 миллионов транзакций, из которых около 60 миллионов остались неизрасходованными.



В отличие от полностью проверяющих узлов, существуют легковесные узлы, также называемые тонкими клиентами или клиентами Simple Payment Verification (SPV).

Фактически, подавляющее большинство узлов в сети Биткойн – это легкие узлы.

Они отличаются от полностью проверяющих узлов тем, что они не хранят полную цепочку блоков.

Они хранят только те части, которые им необходимы, чтобы проверить конкретные транзакции, которые им интересны.

Если вы используете программу кошелька, она обычно включает узел Simple Payment Verification (SPV).

Узел загружает заголовки блоков и транзакции, которые представляют платежи на ваши адреса.

У узла SPV нет уровня безопасности полностью проверяющего узла.

1
...
...
13