Причина хеширования одноразового номера в prevBlockHash?

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

Но вот что я спрашиваю: учитываем ли мы одноразовый номер при prevBlockHashвычислении предыдущего блока, потому что он уже есть в заголовке блока (для вычисления доказательства работы), и было бы глупо писать calcPrevBlockHashфункцию, которая вычисляет заголовок предыдущего блока, игнорируя одноразовый номер?

Или есть особое свойство безопасности или гарантия, которую мы получаем при включении одноразового номера в prevBlockHashвычисление последующего блока?

Например, вы можете возразить, что мы хешируем метку времени, потому что хотим зафиксировать время создания блока. Смотрите ответ здесь: Почему компонент метки времени в заголовке блока? Я думаю, вы можете утверждать то же самое для поля nonce.

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

Это не. Я понимаю, почему нужно изменить одноразовый номер, я задаюсь вопросом, почему его нужно включать в заголовок блока и, таким образом, хэшировать.
Вам все равно придется каким-то образом включать одноразовый номер в хеш блока, иначе что вы меняете, чтобы найти хорошее доказательство работы? И в этом случае любой, кто попытается проверить блок, должен будет получить одноразовый номер или проделать массу дополнительной работы, чтобы восстановить его. Если вы не поместите его в блок, вам придется распространять его каким-то другим способом.
@NateEldredge: 1. «Вам все равно нужно каким-то образом включить одноразовый номер в хэш блока, иначе что вы измените, чтобы найти хорошее доказательство работы?» Нонс конечно. Почему вы должны включать его в хэш блока? 2. «Если вы не поместите это в блок, вам придется распространять его каким-то другим способом». Но я никогда не предлагал не включать одноразовый номер в блок. Мой вопрос связан с тем, почему мы включаем его в заголовок блока . Есть ли причина, по которой его нужно хэшировать, или это «просто так».
@Костас: Итак, у вас есть заголовок блока. Вы вычисляете его хэш. Результат не имеет достаточного количества начальных нулей, чтобы быть действительным доказательством работы. Что теперь? Вы можете делать с одноразовым номером все, что хотите, но это не имеет значения: если его нет в заголовке, то данные, которые вы хешируете, не меняются, и когда вы хэшируете их снова, вы просто получите то же самое не- достаточно хорошее хэш-значение. В конце концов, хеш-функция — это функция ; предоставление ему одного и того же ввода всегда дает один и тот же результат.
@NateEldredge: мы говорим о разных процессах хеширования. Есть процесс, в котором вы пытаетесь придумать хеш заголовка блока, который меньше целевого. Здесь имеет смысл рассмотреть одноразовый номер. (На самом деле одноразовый номер является ключевым элементом в этом расчете хэша.) Это то, на что вы ссылаетесь, и мы согласны. Однако я имею в виду другой процесс хэширования, который происходит, когда я хочу создать блок n+1 и хочу сослаться на блок n по его prevBlockHash.
Тогда я спрашиваю: есть ли какое-то конкретное свойство, определяющее, почему нам нужно включать одноразовый номер в этот prevBlockHashхэш? Или это что-то вроде: «Ну, это часть заголовка, потому что он нужен нам для вычисления доказательства выполнения работы prevBlockHash. какие-либо дополнительные гарантии, делая это), но было бы излишним кодировать calcPrevBlockHashфункцию, которая игнорирует nonceполе, поэтому мы просто включаем его в наши prevBlockHashвычисления».
@Костас: Хорошо, теперь я думаю, что понял твой вопрос. В нынешнем виде эти два процесса являются одним и тем же! Я полагаю, что в принципе вы могли бы сделать их отдельными и исключить одноразовый номер из последнего, но это ничего не дает и добавляет ненужную сложность.
@NateEldredge: Верно. hashBlockHeader()это то, что вы используете для расчета доказательства работы и prevBlockHashрасчета сейчас. (Примечание: выдуманные имена функций.) Все, о чем я спрашиваю: если бы вы вычисляли prevBlockHash, используя calcPrevBlockHash()функцию, которая игнорирует поле nonce, не сломало бы это что-нибудь? Вы бы потеряли какие-либо свойства безопасности, которые были бы в настоящее время?

Ответы (2)

После комментариев, я думаю, ваш вопрос сводится к следующему:

Для prevBlockHashполя заголовка блока при вычислении хэша заголовка предыдущего блока можем ли мы исключить его значение nonce?

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

Однако смысла в этом не было бы. Нам уже нужно вычислить хэш предыдущего заголовка, включая одноразовый номер, чтобы убедиться, что это доказательство работы соответствующей сложности. Сделав это, мы могли бы также использовать это значение в качестве «идентификатора блока» для всех целей, включая prevBlockHash. Вычисление другого хеш-значения, за исключением одноразового номера, потребует больше кода, больше времени разработчика и больше времени вычислений; добавит возможность ошибок в самом коде хеширования; и может привести к большой путанице, когда люди попытаются отследить, какая часть кода использует какой хэш. Все это в обмен на какую-либо выгоду, насколько я могу судить.

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

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

Если бы не было nonce, нам пришлось бы менять что-то еще в заголовке блока для каждой попытки. Это оставит только метку времени или корень Merkle. Другие элементы заголовка фиксированы.
Временная метка неудобна, потому что мы хотели бы, чтобы она показывала фактическое время. Итак, нам придется изменить корень Merkle.

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

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

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

а) должно быть изменено, и
б) должно быть в заголовке блока. ;)

Это не отвечает на мой вопрос, но это не ваша вина :) Я переписал вопрос, чтобы прояснить свою точку зрения. Я понимаю использование одноразового номера. Я спрашиваю, почему это нужно учитывать при расчете prevBlockHash(в следующем блоке).
Я только что прочитал ваш вопрос еще раз, и я не понимаю, что вы пытаетесь спросить. Если бы одноразовый номер не был частью того, что хэшируется, он бы а) не способствовал хэшированию блока, б) мог быть произвольным и в) не имел бы смысла. Если его нет в хешированной части блока, зачем вообще его добавлять. Однако я уже рассказал, какова его функция в моем ответе. Итак, я действительно запутался сейчас.
Я думаю, чего не хватает, так это того, что я имею в виду prevBlockHashхеш, тогда как вы ссылаетесь на вычисление хэша для доказательства работы. Все, о чем я спрашиваю, сломается ли что-нибудь (или потеряете ли вы важное свойство безопасности), если вы напишете calcPrevHashфункцию, которая игнорирует поле nonce. Я еще раз переписал вопрос, чтобы прояснить это.