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

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

nBits

Другие названия: Компактное целевое значение.

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

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

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

nBits читается как один байт показателя степени, за которым следует трехбайтовый коэффициент, и вместе они образуют полное 256-битное число.

Возьмите значение, которое несет генезис-блок, 0x1d00ffff. Показатель степени равен 0x1d, то есть 29, а коэффициент равен 0x00ffff, то есть 65 535. Следовательно, целевое значение равно 65 535, умноженному на 2 в степени 208, а это число записывается как восемь шестнадцатеричных нулей, затем ffff, затем нули до 64 цифр. Это самое легкое целевое значение, которое допускает mainnet, и оно является определением сложности 1.

Есть две особенности, которые часто вводят в заблуждение. Первая связана с точностью. Коэффициент всего в 24 бита не может выразить произвольное 256-битное число, поэтому закодированное целевое значение всегда округлено, и обратное преобразование от целевого значения к nBits и обратно не всегда возвращает исходное значение. Вторая связана с битом знака. Если старший бит коэффициента установлен, значение считается отрицательным, поэтому кодировщики сдвигают коэффициент на байт вниз и повышают показатель степени для компенсации. Именно поэтому значение генезис-блока выглядит как 0x1d00ffff, а не как более очевидное 0x1cffff00, и поэтому ведущий нулевой байт внутри коэффициента является нормой, а не ошибкой.

В сериализованном заголовке поле находится по смещению байта 72 и записывается в порядке little endian, так что эти четыре байта на диске и в сети выглядят как ff ff 00 1d.

Где это встречается

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

Обозреватели блоков называют его "bits" и печатают шестнадцатеричное значение рядом с более понятным показателем сложности. Вызов RPC getblock в Bitcoin Core возвращает его как "bits", а getblocktemplate передает его программному обеспечению для майнинга как требование, которое должен превзойти кандидатный заголовок. В исходном коде это член nBits структуры CBlockHeader, преобразуемый функциями arith_uint256::SetCompact и GetCompact. Майнинговые пулы редко его показывают: Stratum передает те же четыре байта машинам внутри уведомления о задании, и прошивке никогда не приходится задумываться, что они означают.

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

nBits vs пороговое целевое значение

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

Не путать с

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

nBits и сложность означают одно и то же?

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

Почему генезис-блок использует 0x1d00ffff?

Потому что это самое легкое целевое значение, которое биткоин допускает в mainnet, закодированное так, чтобы старший бит коэффициента оставался нулевым. В декодированном виде это 65 535, умноженное на 2 в степени 208, что и означает сложность 1.

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

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

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