Skip to content

Идентификаторы транзакций и блоков ​

Типы идентификаторов VIZ унаследовал от Graphene (BitShares, затем Steem). В исходниках они объявлены как fc::ripemd160, и старая документация и библиотеки называют их «ripemd160 id». Это только имя 20-байтового контейнера, в котором они хранятся: ни один из этих id не является ripemd160-хэшем. Нода объявляет их через алиас id160_type, чтобы сказать это прямо.

ЗначениеКак вычисляетсяРазмер
transaction_idпервые 20 байт sha256(сериализованная транзакция), подписи не входят20 байт
block_idпервые 20 байт sha224(сериализованный заголовок блока), затем байты 0–3 заменяются номером блока (big-endian)20 байт
transaction_merkle_rootripemd160 от корня sha256-дерева по подписанным транзакциям20 байт

Merkle root — единственное значение, которое действительно ripemd160.

Что это значит для клиентов ​

  • Чтобы посчитать id транзакции, сериализуйте её без signatures, возьмите sha256 и оставьте первые 20 байт. ripemd160 не применять — результат никогда не совпадёт с нодой.
  • Номер блока читается прямо из block id: это первые 4 байта, big-endian. TaPoS (ref_block_num / ref_block_prefix) берёт младшие 16 бит этого номера и байты 4–7 block id.
  • Id имеют длину 20 байт во всех ответах API, в block log и в истории аккаунтов. Смена хэша (на настоящий ripemd160 или на полный 32-байтовый sha256) была бы хардфорком, который делит историю на два формата id, без выигрыша в безопасности: 160 бит для идентификатора достаточно, а подпись ставится на полный sha256-дайджест, а не на id.

Исходники: transaction::id() в libraries/protocol/transaction.cpp, signed_block_header::id() и signed_block::calculate_merkle_root() в libraries/protocol/block.cpp, типы — в libraries/protocol/include/graphene/protocol/types.hpp.