Вики ZooBC
Безопасность и архитектура

Подписи, привязанные к цепочке

Подпись ZooBC действительна только в одной цепочке. Прежде чем подписать транзакцию, кошелёк вычисляет дайджест, включающий хеш генезиса цепочки, поэтому платёж, подписанный в testnet, не проходит проверку в mainnet или devnet, хотя один и тот же ключ даёт один и тот же адрес во всех цепочках. Та же привязка защищает соединения между узлами и сообщения, подписанные вне цепочки.

Дайджест

Подписант никогда не подписывает сырые байты транзакции. Он подписывает такой дайджест:

digest           = SHA3-256("ZBC-TX" ‖ genesis hash ‖ unsigned transaction bytes)
transaction hash = SHA3-256(unsigned transaction bytes ‖ signature)
transaction id   = the first 8 bytes of the transaction hash, little-endian

Метка «ZBC-TX» помечает дайджест как дайджест транзакции; другие подписываемые действия используют другие метки (см. ниже). Хеш генезиса привязывает подпись к одной цепочке. Принимается только этот дайджест, привязанный к цепочке: подпись над голыми байтами, без привязки к цепочке, отклоняется в любой цепочке. Полная процедура подписания описана в статье подписание транзакции.

Дайджест из ZBC-TX, хеша генезиса (идентичности цепочки) и байтов транзакции проходит через SHA3-256 и подписывается. С генезисом testnet подпись подходит; с генезисом mainnet дайджест другой, и транзакция отклоняется.
Дайджест из ZBC-TX, хеша генезиса (идентичности цепочки) и байтов транзакции проходит через SHA3-256 и подписывается. С генезисом testnet подпись подходит; с генезисом mainnet дайджест другой, и транзакция отклоняется.

Хеш генезиса — идентичность цепочки

Хеш генезиса — это хеш самого первого блока цепочки. Он выводится из конфигурации генезиса цепочки, поэтому изменение любого зафиксированного значения этой конфигурации даёт новый хеш, то есть другую цепочку (см. Генезис-блок). Отдельного байта идентификатора сети в ZooBC нигде нет: хеш генезиса — единственная идентичность цепочки. У devnet, testnet и mainnet он свой (см. Devnet, testnet и mainnet), а тестовая сеть, запущенная заново, получает новый.

Узел сообщает genesis_hash своей цепочки и свою signing_version в информационном маршруте /api/v1/node/info (см. API узла), так что кошелёк или инструмент может узнать, для какой цепочки он подписывает.

Повторное воспроизведение между цепочками

Допустим, платёж подписан в testnet, и кто-то копирует его в mainnet. Узел mainnet вычисляет дайджест с хешем генезиса mainnet, получает другое значение, и подпись не проходит проверку: транзакция отклоняется как «not signed for this chain». Сумма роли не играет, и кошельку ничего не нужно добавлять.

Один и тот же ключ даёт один и тот же адрес во всех цепочках ZooBC, и адрес, пополненный в одной цепочке, в другой просто показывает нулевой баланс. Именно поэтому привязка важна: без неё платёж, сделанный в одной цепочке, можно было бы скопировать в другую и переместить там монеты.

Каждый тип аккаунта, каждый подписант

Аккаунтами ZooBC могут управлять ключи многих видов: собственные ключи Ed25519 ZooBC, ключи Bitcoin и Ethereum и другие (см. Ключи и типы аккаунтов). Каждый тип аккаунта подписывает один и тот же дайджест, привязанный к цепочке; некоторые сначала хешируют его ещё раз, как того требует схема подписи их родной цепочки (например, ключи в стиле Ethereum подписывают его хеш Keccak-256). Участники мультиподписного аккаунта подписывают привязанный к цепочке дайджест внутренней транзакции.

Другие подписываемые действия используют собственные дайджесты, тоже привязанные к цепочке: согласия на привязку к группам аккаунтов и управление ими («ZBC-GROUP-LINK», «ZBC-GROUP-CONTROL»), соподпись многостороннего эскроу и запрос, который отменяет ожидающую транзакцию в пуле узла («ZBC-CANCEL»).

Узлы и сообщения

Привязка к цепочке не ограничивается транзакциями:

  • Рукопожатие пиров. Когда два узла соединяются, рукопожатие подписывается ключом узла и несёт хеш генезиса. Пир другой цепочки отклоняется с сообщением «Genesis hash mismatch», поэтому узел одной цепочки никогда не становится пиром узла другой.
  • Подписанные сообщения. Сообщения, подписанные вне цепочки с помощью инструментов, используют дайджест SHA3-256("ZBC-MSG-v2" ‖ хеш генезиса ‖ сообщение), поэтому сообщение, подписанное в devnet, никогда не проходит проверку в testnet или mainnet (см. Подписанные и зашифрованные сообщения).

Исключение внутри протокола — квитанции: квитанция не называет цепочку, поэтому собственной привязки к цепочке у неё нет. Но она называет опорный блок по высоте и хешу, и валидаторы это проверяют.

См. также