Block ChainВ¶
The following subsections briefly document core block details.
Block HeadersВ¶
Block headers are serialized in the 80-byte format described below and then hashed as part of Bitcoin’s proof-of-work algorithm, making the serialized header format part of the consensus rules.
The block version number indicates which set of block validation rules to follow. See the list of block versions below.
A SHA256(SHA256()) hash in internal byte order of the previous block’s header. This ensures no previous block can be changed without also changing this block’s header.
merkle root hash
A SHA256(SHA256()) hash in internal byte order. The merkle root is derived from the hashes of all transactions included in this block, ensuring that none of those transactions can be modified without modifying the header. See the merkle trees section below.
The block time is a Unix epoch time when the miner started hashing the header (according to the miner). Must be strictly greater than the median time of the previous 11 blocks. Full nodes will not accept blocks with headers more than two hours in the future according to their clock.
An encoded version of the target threshold this block’s header hash must be less than or equal to. See the nBits format described below.
An arbitrary number miners change to modify the header hash in order to produce a hash less than or equal to the target threshold. If all 32-bit values are tested, the time can be updated or the coinbase transaction can be changed and the merkle root updated.
The hashes are in internal byte order; the other values are all in little-endian order.
An example header in hex:
Block VersionsВ¶
Version 1 was introduced in the genesis block (January 2009).
Version 2 was introduced in Bitcoin Core 0.7.0 (September 2012) as a soft fork. As described in BIP34, valid version 2 blocks require a block height parameter in the coinbase . Also described in BIP34 are rules for rejecting certain blocks; based on those rules, Bitcoin Core 0.7.0 and later versions began to reject version 2 blocks without the block height in coinbase at block height 224,412 (March 2013) and began to reject new version 1 blocks three weeks later at block height 227,930.
Version 3 blocks were introduced in Bitcoin Core 0.10.0 (February 2015) as a soft fork. When the fork reached full enforcement (July 2015), it required strict DER encoding of all ECDSA signatures in new blocks as described in BIP66. Transactions that do not use strict DER encoding had previously been non-standard since Bitcoin Core 0.8.0 (February 2012).
Version 4 blocks specified in BIP65 and introduced in Bitcoin Core 0.11.2 (November 2015) as a soft fork became active in December 2015. These blocks now support the new OP_CHECKLOCKTIMEVERIFY opcode described in that BIP.
The mechanism used for the version 2, 3, and 4 upgrades is commonly called IsSuperMajority() after the function added to Bitcoin Core to manage those soft forking changes. See BIP34 for a full description of this method.
As of this writing, a newer method called version bits is being designed to manage future soft forking changes, although it’s not known whether version 4 will be the last soft fork to use the IsSuperMajority() function. Draft BIP9 describes the version bits design as of this writing, although it is still being actively edited and may substantially change while in the draft state.
Merkle TreesВ¶
The merkle root is constructed using all the TXIDs of transactions in this block, but first the TXIDs are placed in order as required by the consensus rules:
The coinbase transaction’s TXID is always placed first.
Any input within this block can spend an output which also appears in this block (assuming the spend is otherwise valid). However, the TXID corresponding to the output must be placed at some point before the TXID corresponding to the input. This ensures that any program parsing block chain transactions linearly will encounter each output before it is used as an input.
If a block only has a coinbase transaction, the coinbase TXID is used as the merkle root hash.
If a block only has a coinbase transaction and one other transaction, the TXIDs of those two transactions are placed in order, concatenated as 64 raw bytes, and then SHA256(SHA256()) hashed together to form the merkle root.
If a block has three or more transactions, intermediate merkle tree rows are formed. The TXIDs are placed in order and paired, starting with the coinbase transaction’s TXID. Each pair is concatenated together as 64 raw bytes and SHA256(SHA256()) hashed to form a second row of hashes. If there are an odd (non-even) number of TXIDs, the last TXID is concatenated with a copy of itself and hashed. If there are more than two hashes in the second row, the process is repeated to create a third row (and, if necessary, repeated further to create additional rows). Once a row is obtained with only two hashes, those hashes are concatenated and hashed to produce the merkle root.
Example Merkle Tree Construction В¶
TXIDs and intermediate hashes are always in internal byte order when they’re concatenated, and the resulting merkle root is also in internal byte order when it’s placed in the block header.
Target nBitsВ¶
The target threshold is a 256-bit unsigned integer which a header hash must be equal to or below in order for that header to be a valid part of the block chain. However, the header field nBits provides only 32 bits of space, so the target number uses a less precise format called “compact” which works like a base-256 version of scientific notation:
Converting nBits Into A Target Threshold В¶
As a base-256 number, nBits can be quickly parsed as bytes the same way you might parse a decimal number in base-10 scientific notation:
Quickly Converting nBits В¶
Although the target threshold should be an unsigned integer, the original nBits implementation inherits properties from a signed data class, allowing the target threshold to be negative if the high bit of the significand is set. This is useless—the header hash is treated as an unsigned number, so it can never be equal to or lower than a negative target threshold. Bitcoin Core deals with this in two ways:
When parsing nBits, Bitcoin Core converts a negative target threshold into a target of zero, which the header hash can equal (in theory, at least).
When creating a value for nBits, Bitcoin Core checks to see if it will produce an nBits which will be interpreted as negative; if so, it divides the significand by 256 and increases the exponent by 1 to produce the same number with a different encoding.
Some examples taken from the Bitcoin Core test cases:
Источник
Bitcoin in a nutshell — Blockchain
Blockchain — это технология, на базе которой построен Bitcoin. И если пару лет назад вся слава доставлась криптовалюте, то сегодня все чаще можно слышать смелые фразы вроде: «Forget Bitcoin, Long Live Blockchain». Активно развиваются платформы вроде Ethereum, IPFS или Overstock, которые рассматривают блокчейн не как инструмент для создания еще одной платежной системы, а как совершенно обособленную технологию, сравнимую по своей инновационности разве что с Интернетом.
В этой главе я расскажу вам, что из себя представляет блокчейн Bitcoin. Даже по сравнению с Ethereum, это жуткий анахронизм, но понимание принципов его работы вам сильно поможет, если вы решите разобраться с более сложными проектами.
Table of content
Blockchain for dummies
Сам по себе блокчейн — это крайне простая штука. Его проще всего проиллюстрировать на примере книги бухгалтерского учета, в которую записываются все транзакции в сети Bitcoin. Более того, такая книга присутствует у каждого участника сети, а значит любой, при желании, может проверить, была та или иная транзакция в реальности или нет.
И если блокчейн целиком — это книга, то отдельные блоки можно представлять как страницы, на которых «записываются» транзакции. Кажый блок «ссылается» на предыдущий и так до самого первого блока (genesis block). Именно это и создает такую интересную особенность блокчейна, как неизменяемость. Нельзя взять и изменить блок #123 так, чтобы этого никто не заметил. Потому что блокчейн устроен таким образом, что это повлечет изменение блока #124, потом #125 и так далее, до самого верха.
Structure
Привычным движением руки открываем спецификацию протокола и смотрим на структуру блока.
- version — версия блока
- prev_block — хэш предыдущего блока (parent block)
- merkle_root — если упрощенно, то это хэш всех транзакций в блоке
- timestamp — дата и время создания блока
- bits, nonce — про эти параметры я подробно расскажу в главе Bitcoin in a nutshell — Mining
- txn_count, txns — число транзакций в блоке и их список
Первые шесть параметров (все кроме txn_count и txns) образуют заголовок блока (header). Именно хэш заголовка называют хэшем блока, то есть сами транзакции непосредственного участия в хэшировании не принимают.
Вместо этого они заносятся в особую структуру — дерево Меркла, про которую я расскажу ниже.
Merkle tree
Technical side
Дерево Меркла — это структура данных, также известная как бинарное дерево хэшей. В случае Bitcoin оно строится следующим образом:
Сначала считаются хэши всех транзакций в блоке hash_A = SHA256(SHA256(A))
Потом считаются хэши от суммы хэшей транзакций hash_AB = SHA256(SHA256(hash_A + hash_B))
Точно также считаем хэши от суммы получившихся хэшей hash_ABCD = SHA256(SHA256(hash_AB + hash_CD)) и далее по рекурсии. Лирическое отступление — так как дерево бинарное, то на кажом шаге должно быть четное число элементов. Поэтому если, например, у нас только три транзакции, то последняя транзакция просто дублируется:
Процесс продолжается до тех пор, пока не получится один единственный хэш — он и называется merkle_root (третье поле в header блока)
Ниже приведена реализация дерева Меркла, можете проверить ее на каком-нибудь блоке.
Immutability
Теперь о том, зачем это нужно в Bitcoin. Я думаю, вы понимаете, что если изменить хотя бы одну транзакцию, то merkle_root также изменится. Поэтому такая структура данных позволяет обеспечить «неподделываемость» транзакций в блоке. То есть не может произойти следующей ситуации:
Кто-то из майнеров нашел новый блок и начал раскидывать его по сети. В это время злоумышленник перехватывает блок и, например, удаляет из блока какую-нибудь транзакцию, после чего распостраняет уже измененный блок.
Для проверки достаточно посчитать merkle_root самостоятельно и сравнить его с тем, что записан в header блока.
Но здесь можно резонно возразить, что, во-первых, такие сложности совершенно ни к чему. Достаточно просто посчитать хэш от суммы всех транзакций в блоке txns_hash = SHA256(SHA256(sum(txns))) — он точно также изменится после любых манипуляций с транзакциями. А, во-вторых, что мешает злоумышленнику подменить merkle_root в блоке? На второй вопрос отвечу сразу: на самом деле в блоке вообще нельзя ничего изменить, потому что блок тут же станет невалидным (это вы поймете после прочтения следующей главы Bitcoin in a nutshell — Mining).
А дерево Меркла нужно на самом деле для того, чтобы иметь возможность создавать SPV nodes (Simplified Payment Verification). Такие ноды синхронизируют только заголовки блоков, без самих транзакций. В результате блокчейн занимает на порядок меньше места (для красоты возьмем высоту в 500.000 блоков, размер header фиксирован — 80 байт):
500.000 * 80 / 1024 / 1024 ≈ 40 Мб
Такой блокчейн уже можно без проблем уместить на телефоне, планшете или каком-нибудь IoT. Что в перспективе должно дать большую децентрализацию, безопасность сети и так далее.
Суть упрощенной верификации платежей в следующем: пусть у вас есть SPV нода. У меня же есть весь блокчейн целиком и мне нужно вас убедить, что какая-нибудь транзакция действительно была (на картинке это транзакция K). В этом случае, мне достаточно всего лишь предоставить вам несколько хэшей: H_L, H_IJ, H_MNOP, H_ABCDEFGH , они еще называются authentication path.
После чего вы сначала считаете H_K = SHA256(SHA256(K)) , потом H_KL = SHA256(SHA256(H_K + H_L)) и так до самого верха. Если в итоге вы находите у себя блок с таким же merkle_root, то факт существования транзакции считается подтвержденным.
BTW Ральф Меркл даже запатентовал свою структуру данных, о чем свидетельствует патент US4309569 A.
Timestamp
Еще один интересный вопрос. Представим, что где-то в сети появился появился новый блок и ноды начинают передавать его друг-другу. Каждая нода должна убедиться в том, что блок корректен. Для этого она:
- проверяет синтаксис и структуру блока
- проверяет на валидность каждую транзакцию в блоке
- хэширует транзакции и сравнивает merkle root
- проверяет несколько критериев, связанных с майнингом, и так далее
Но как можно проверить timestamp? Понятно, что время на разных компьютерах может различаться, так что даже если у нового блока timestamp отличается от вашего текущего времени на час вперед, это еще не значит, что блок «неправильный», может у майнера просто часы спешат.
Поэтому для проверки timestamp на валидность было придумано два критерия. Во-первых, он должен быть больше, чем среднее арифметическое timestamp-ов предыдущих 11 блоков. Это делается для того, чтобы не получилось так, что блок #123 вышел 12 марта 2011 года, а #124 — 13 февраля 1984. Но в тоже время допускается некоторая погрешность.
Во-вторых, timestamp должен быть меньше чем network adjusted time. То есть нода, при получении нового блока, интересуется текущим временем у своих «соседей» по сети, считает среднее арифметическое и если block timestamp меньше получившегося значения + 2 часа, то все в порядке.
BTW как вы видите, timestamp нового блока может оказаться даже меньше, чем timestamp более раннего блока. Это не такая уж и редкость, например #145045, #145046 и #145047.
Raw block
Если у вас до сих остались какие-то вопросы по структуре блока, то предлагаю вам посмотреть на них в «сыром» виде. Самый очевидный способ это сделать — запустить на пару часов bitcoind —daemon , а потом исследовать уже скачанные блоки. Но, во-первых, не у всех есть время / желание синхронизировать блокчейн. Во-вторых, в Bitcoin блоки хранятся в крайне специфической базе данных LevelDB, еще и довольно странным образом. А так как книга расчитана не только на опытных разработчиков, то я пойду уже проверенным путем и снова использую протокол в его первозданном виде.
Для получения блока отправим сообщение getdata, в котором укажем type : MSG_BLOCK и hash : 000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506 — это хэш блока #100.000. Весь код целиком можете посмотреть здесь.
Источник