Глоссарий / Транзакции и комиссии
Хеш подписи
Другие названия: Sighash.
- Что такое хеш подписи?
- Хеш подписи представляет собой дайджест, который кошелек фактически подписывает: заново собранную копию транзакции, урезанную в соответствии с флагом, выбранным для этого входа, а затем дважды хешированную с помощью SHA-256.
Определено в BIP-143.
Ни одна подпись не охватывает транзакцию в том виде, в каком она передается по сети. Для каждого входа вычисляется собственный дайджест, построенный по процедуре, которую переписывали дважды: исходная версия 2009 года, BIP143 для входов segwit и BIP341 для Taproot. То, что дайджест оставляет за своими рамками, злоумышленник может изменить беспрепятственно.
Как это работает
Построение хеша подписи означает создание измененной копии транзакции и хеширование именно этой копии, а не транзакции, которую вы собираетесь отправить в сеть.
Исходная процедура устроена так. Возьмите транзакцию, очистите скрипт разблокировки у каждого входа, вставьте скрипт, который расходуется, в единственный вход, который вы подписываете, затем сохраните, обнулите или отбросьте выходы в соответствии с флагом. Добавьте флаг как четырехбайтовое число, дважды примените SHA-256 ко всему этому и подпишите 32 байта, которые получатся.
У этой конструкции была цена, которую никто не замечал, пока транзакции не выросли. Поскольку каждый вход пересобирает и повторно хеширует всю транзакцию, объем работы растет как квадрат числа входов. BIP143 приводит цифры: проверка обычного блока на 1 МБ занимает примерно 2 секунды, а одна намеренно составленная транзакция на 1 МБ с 5569 операциями подписи может занять 25 секунд. Одна транзакция, задерживающая каждый узел сети на столько времени, представляет собой отказ в обслуживании, готовый к промышленному применению.
BIP143 переписал процедуру для входов segwit версии 0 и решил сразу две проблемы. Три промежуточных хеша, охватывающие outpoints, порядковые номера и выходы, вычисляются один раз и повторно используются для каждого входа, что делает затраты линейными. Что важнее для любого, кто хранит биткоины, дайджест теперь фиксирует стоимость подписываемого входа. До этого устройству подписи приходилось сообщать, сколько стоит вход, без возможности это проверить, поэтому вредоносная программа могла занизить стоимость входов и заставить аппаратный кошелек одобрить огромную комиссию.
BIP341 переписал процедуру в третий раз, для Taproot. Дайджест Taproot является тегированным хешем, к которому добавлена строка домена, чтобы его никогда нельзя было спутать с дайджестом другого протокола, и он фиксирует суммы и скрипты блокировки всех расходуемых входов, а не только подписываемого. Он также вводит значение флага по умолчанию, равное нулю, которое охватывает все, что охватывает стандартное правило, но никогда не записывается в подпись.
Где это встречается
С хешем подписи вы сталкиваетесь косвенно, как с причиной того, почему ваш аппаратный кошелек ведет себя именно так.
Подписание legacy-входа требует передать устройству полную предыдущую транзакцию, потому что только так оно может самостоятельно установить стоимость входа. Sparrow и Electrum передают эти транзакции на Trezor или Ledger перед подписанием, и в кошельке, полном старых биткоинов, именно из-за этого шага расход занимает заметно больше времени, чем вы ожидаете. Входу segwit нужна только сумма, которая уже есть в PSBT.
Хеш подписи виден напрямую как последний байт подписи legacy или segwit в обозревателе блоков. Подпись, оканчивающаяся на 01, была создана по правилу, охватывающему все. Любое другое значение стоит понять, прежде чем полагаться на транзакцию.
Хеш подписи vs SIGHASH_ALL
Хеш подписи является дайджестом; SIGHASH_ALL представляет собой одно из правил его построения. У каждой подписи есть хеш подписи, включая подписи Taproot, которые вообще не несут байта флага. Различается лишь то, какие части транзакции вошли в дайджест, и флаг является просто обозначением этого выбора. Утверждение, что транзакция «использует SIGHASH_ALL», описывает политику; утверждение, что у нее есть хеш подписи, описывает то, что было у каждой подписи биткоина за всю его историю.