Перейти к содержимому
buybitcoinsmart

Глоссарий / Майнинг и консенсус

Сериализованный блок

Что такое сериализованный блок?
Сериализованный блок представляет собой точную последовательность байтов, в которую блок превращается при передаче по сети или на диске: заголовок из 80 байт, число транзакций, а затем все транзакции по порядку.

Определено в BIP-144.

Сериализация представляет собой способ, которым абстрактный блок превращается в нечто, что можно хешировать, отправлять и хранить. Генезис-блок сериализуется в 285 байт: 80 приходится на заголовок, 1 на число транзакций и 204 на его единственную coinbase-транзакцию. Если вы когда-либо вставляли сырой hex в обозреватель блоков или запускали getblock с verbosity 0, вы смотрели именно на это.

Как это работает

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

Заголовок всегда занимает 80 байт в таком порядке: версия в 4 байта, хеш предыдущего заголовка в 32 байта, корень Меркла в 32 байта, метка времени в 4 байта, кодировка цели nBits в 4 байта и nonce в 4 байта. Затем идет число транзакций, записанное в compactSize, целое число переменной длины, которое занимает 1 байт для значений меньше 253 и до 9 байт для любых огромных значений. Потом сами транзакции, каждая полностью сериализована, первой идет coinbase.

С BIP144 у одного и того же блока есть две допустимые сериализации. Форма без свидетелей полностью опускает данные свидетелей, и именно ее ожидает программное обеспечение версий до 2017 года. Полная форма включает их, помечая каждую транзакцию со свидетелем байтом 0x00 и следующим за ним флагом 0x01 там, где иначе стояло бы число входов. Обе кодируют один и тот же блок и обе дают одинаковый хеш блока, потому что хеш охватывает только эти 80 байт заголовка, а корень Меркла внутри них фиксирует идентификаторы транзакций, которые вычисляются из кодировки без свидетелей. Это разделение и есть буквальный смысл segregated witness.

Одна привычка ловит каждого хотя бы раз: многобайтовые целые числа записываются в порядке little endian, поэтому метка времени 0x495FAB29 на проводе выглядит как 29 ab 5f 49, а хеши отображаются в обратном порядке относительно порядка своих сериализованных байтов. Хеш блока, который вы копируете из обозревателя, не является последовательностью байтов, лежащей в файле.

Где это видно

Сериализованные блоки передаются по одноранговой сети внутри сообщения block. Каждое сообщение несет сначала конверт из 24 байт: стартовую строку в 4 байта, f9beb4d9 в mainnet, имя команды в 12 байт, длину полезной нагрузки в 4 байта и контрольную сумму в 4 байта, взятую из первых четырех байтов двойного SHA-256 от полезной нагрузки. Bitcoin Core ограничивает полезную нагрузку любого отдельного сообщения значением 4 000 000 байт, это сетевой предел, а не консенсусный.

Те же байты попадают на ваш диск. Bitcoin Core дописывает блоки в файлы с именами blk00000.dat и далее, каждый ограничен 128 MiB, с такой же стартовой строкой и префиксом длины перед каждым блоком, чтобы файл можно было сканировать последовательно. Генезис-блок является исключением: он скомпилирован в программное обеспечение как константа, а не загружается, и именно поэтому он служит якорем, с которым синхронизирующийся узел сверяет все остальное.

В повседневном использовании сериализация проявляется через RPC getblock с verbosity 0, через вкладку сырых данных или hex в большинстве обозревателей и внутри инструментов, позволяющих декодировать блок вручную. Каждый, кто проверяет, сказал ли ему обозреватель правду, приходит сюда, потому что hex является единственным представлением, которое никто не переформатировал.

Сериализованный блок vs блок

Блок является объектом; сериализованный блок является одной из его кодировок. Различие было косметическим до 2017 года, когда SegWit дал каждому блоку две допустимые кодировки разной длины, и размер блока стал вопросом, требующим уточнения. Bitcoin Core отвечает на него тремя способами в одном ответе RPC: size для полной сериализации, strippedsize для версии без свидетелей и weight для числа, которое фактически проверяют правила.

Не путать с

Часто задаваемые вопросы

Почему у блока два разных размера?

Потому что SegWit дал каждому блоку две допустимые сериализации. Форма без свидетелей опускает данные свидетелей, а полная форма их включает, поэтому Bitcoin Core сообщает size, strippedsize и weight для одного и того же блока по отдельности.

Является ли хеш блока хешем всего сериализованного блока?

Нет. Это двойной SHA-256 только от заголовка в 80 байт. Транзакции охвачены косвенно, через корень Меркла, зафиксированный внутри этого заголовка.

Связанные термины

Еще в разделе «Майнинг и консенсус»

Читать эту страницу на английском