Блок Bitcoin и дерево Меркла
В mempool библиотека наблюдает кандидата на оплату. Блок связывает множество транзакций с заголовком и предыдущей историей. Разберём, какую проверку даёт дерево Меркла и почему доказательство включения само по себе ещё не доказывает принятие платежа по нашей политике.
В собственном примере блок содержит четыре условных идентификатора: T0, T1, PAYMENT_A, T3. Это метки, а не реальные хеши. Мы вручную рассматриваем структуру и не вычисляем заголовки или доказательства в работающем узле.
Заголовок и содержание
Заголовок содержит сведения, связывающие блок с предыдущим блоком, обязательства относительно транзакций и параметры проверки работы. Идентификатор блока получают по установленной бинарной сериализации заголовка. Тело содержит транзакции, которые узел должен также проверить. Корректный заголовок не освобождает от проверки содержимого.
Ссылка на предыдущий блок образует цепочку. Если заменить содержание старого блока, соответствующие обязательства и идентификаторы меняются, а следующие ссылки уже не совпадут. Однако неизменность здесь обеспечивается совместно структурой ссылок, проверками и накопленной работой. Один связный список хешей без этих правил не создаёт свойства Bitcoin.
Для сайта особенно важна связь высоты и хеша. Высота — положение блока в некоторой цепочке. На той же высоте могут существовать разные кандидаты. Поэтому запись height=102 недостаточна для подтверждения, что два наблюдателя обсуждают одну историю. Сохраняем blockhash, а высоту используем для порядка и расчёта глубины.
Сведение транзакций к корню
Дерево Меркла объединяет идентификаторы попарно, затем объединяет полученные значения до одного корня. Упрощённая схема нашего блока:
T0 T1 PAYMENT_A T3
\ / \ /
H01 H23
\ /
ROOT
В реальной структуре важны правила бинарного соединения, хеширования и обработки нечётного количества элементов. Схема показывает зависимость, а не заменяет реализацию протокола. Если меняется PAYMENT_A, меняется его родитель и затем корень. Не нужно пересчитывать независимую ветвь H01, чтобы понять эту зависимость.
Предположим, читатель получил PAYMENT_A, соседний T3 и значение H01 с указанием порядка. Он может восстановить путь до корня, не получая каждую другую транзакцию. Такое доказательство включения компактно по отношению к числу элементов. Но сторона, отправившая путь, может также прислать произвольный недоверенный корень.
Чтобы доказательство было полезно, корень должен быть связан с заголовком, который проверяется в требуемой модели доверия. Наш сервер с полным узлом получает сведения о принятом блоке через свой источник. Если вместо этого доверяет внешнему веб-сервису, то проверка хешей подтверждает внутреннюю связь данных, но не полностью устраняет доверие к выбору истории.
Что именно включено
Идентификатор транзакции в дереве позволяет говорить о конкретном объекте. Для SegWit существуют дополнительные правила обязательства относительно witness-данных. Поэтому простую схему с txid не следует расширять фразой «корень сам проверяет все подписи»: узел отдельно проверяет транзакционные правила и нужные обязательства.
В блоке есть coinbase-транзакция с особой ролью. Она создаёт допустимую награду и учитывает комиссии по установленным правилам, а её вход не расходует обычный предыдущий UTXO. Новые выходы coinbase имеют ограничение зрелости, которое важно для будущей лаборатории regtest. Нельзя рассматривать любой найденный выход как немедленно расходуемый только потому, что он включён в блок.
Для оплаты курса нас интересует обычный выход библиотеки. Сначала проверяется принадлежность нужной транзакции и выход с правильным условием; затем фиксируется включение в выбранный блок. Сумма 30 000 и номер счёта по-прежнему относятся к прикладной сверке. Включение неправильного получателя не становится правильной оплатой после появления доказательства.
Работа и выбор истории
Bitcoin сравнивает допустимые цепочки по накопленной работе, а не просто по длине списка или по свежести времени в интерфейсе. Заголовок должен соответствовать установленному ограничению proof of work. Узел проверяет эту часть по правилам сети и не принимает заявление майнера «я потратил достаточно ресурсов» вместо результата.
Для библиотеки важен практический вывод: состояние платежа относится к выбранной нашим источником цепочке. Если появляется допустимая ветвь с большей накопленной работой, принадлежность блока может измениться. Мы не обязаны вручную вычислять выбор в веб-приложении, но обязаны сохранять идентификаторы наблюдения и учитывать обновления источника.
Не используем время блока как точную временную отметку поступления заказа. Оно участвует в сетевых ограничениях и не является заверенной записью момента на часах сервера библиотеки. Для срока коммерческого предложения сохраняем собственное серверное время создания и получения наблюдения, а правила отнесения поздней оплаты задаём явно.
Запись наблюдения блока
В платёжном журнале библиотеки сохраним сеть, хеш блока, высоту, хеш предыдущего блока и время получения данных. Для конкретной транзакции добавим позицию или связь включения, если она нужна используемому API. Такая запись позволяет обнаружить, что новый ответ на той же высоте относится к другому блоку.
Ожидаемый переход после включения оплаты — из неподтверждённого наблюдения к одному подтверждению, если блок находится в выбранной ветви. Это условное описание. Если источник недоступен или ещё синхронизируется, старое наблюдение не становится свежим автоматически. Интерфейс должен показывать время последней успешной сверки.
Получение полного контекста
Для диагностики спорного платежа полезно сохранить не только доказательство включения, но и идентификатор источника, хеш заголовка и основание выбора ветви. Один архивированный путь Меркла может оставаться математически корректным относительно старого блока после реорганизации. Изменилось не содержание доказательства, а его место в актуальной истории. В журнале это два разных свойства. Сайт может показать прежнее включение как историческое событие, однако число текущих подтверждений берёт из свежей выбранной цепочки. Так мы избегаем ошибки, когда неизменность маленького доказательства воспринимается как неизменность коммерческого основания.
Структуру заголовка описывает справочник блоков, а обязательства SegWit — BIP 141. Теперь вы можете отделить проверку пути Меркла, проверку блока и решение об оплате. Следующий урок объяснит, как глубина включения меняет наблюдаемое число подтверждений.