Перейти к содержимому
buybitcoinsmart

Глоссарий / Транзакции и комиссии

SIGHASH_SINGLE

Что такое SIGHASH_SINGLE?
SIGHASH_SINGLE представляет собой флаг, который привязывает подпись только к одному выходу, тому, который стоит в списке на той же позиции, что и подписываемый вход.

Вход с номером ноль сопоставляется с выходом с номером ноль, вход с номером один с выходом с номером один, а все остальное в транзакции остается неподписанным. Такое устройство позволяет каждой из нескольких сторон гарантировать собственную выплату внутри одной общей транзакции. Оно же несет в себе самую известную ошибку подписи в биткоине, которая до сих пор содержится в legacy-входах.

Как это работает

Дайджест сохраняет подписываемый вход, версию транзакции, locktime и ровно один выход: тот, индекс которого совпадает с индексом входа.

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

Затем начинается ошибка. В исходном алгоритме, если индекс подписываемого входа больше или равен числу выходов, подходящего выхода для хеширования нет. Вместо того чтобы завершиться с ошибкой, код возвращает фиксированный дайджест: 32-байтовое значение, равное единице. Каждый подписант, оказавшийся в такой позиции, создает подпись над одним и тем же дайджестом, поэтому подпись не привязана к какой-либо конкретной транзакции, и любой, кто способен разместить вход на том же индексе, может ее перенять и повторно использовать. Эта ветка кода сохраняется в Bitcoin Core по сей день, потому что ее удаление изменило бы действительность монет, уже находящихся в цепочке.

Обе переработки алгоритма хеширования подписи закрыли эту ошибку. BIP143 устанавливает, что для входа segwit версии 0 без соответствующего выхода часть дайджеста, относящаяся к выходам, состоит из 32 нулевых байтов, тогда как остальная часть дайджеста по-прежнему фиксирует именно этот вход, так что ничего нельзя повторить. BIP341 идет дальше: на входе Taproot подпись этого типа с индексом за пределами числа выходов просто не проходит проверку.

Где это встречается

Флаг проявляется как завершающий 03 в подписи, и вы встретите его почти исключительно внутри заранее подписанных предложений, а не в обычных платежах.

Схема представляет собой половину транзакции, опубликованную как приглашение. Продавец подписывает утверждение «этот мой вход входит в транзакцию, и выход с совпадающим индексом выплачивает мне запрошенную цену», а затем оставляет остальную часть транзакции пустой, чтобы ее заполнил покупатель. Поскольку подпись продавца игнорирует все остальные входы и выходы, покупатель может добавить собственные средства, собственную сдачу и комиссию по любой ставке, которую требует пул памяти, и гарантия продавца при этом сохраняется. Маркетплейсы Ordinals и Runes построены именно на этом, они распространяют сделки в виде PSBT, и это одна из немногих сделок, действительно не требующих доверия, которые биткоин поддерживает без третьей стороны в середине.

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

SIGHASH_SINGLE vs SIGHASH_ANYONECANPAY

SIGHASH_SINGLE является базовым режимом, а SIGHASH_ANYONECANPAY является модификатором, поэтому они отвечают на разные вопросы. Базовый режим решает, какую долю стороны выходов покрывает подпись: всю, никакую или один совпадающий выход. Модификатор решает, какую долю стороны входов она покрывает: все входы или только подписываемый. Вы выбираете один базовый режим, а затем отдельно решаете, добавлять ли модификатор, поэтому байт флага у реальной подписи обычно является суммой двух, а не каким-то одним из них.

Не путать с

Часто задаваемые вопросы

Что такое ошибка SIGHASH_SINGLE?

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

Можно ли все еще использовать эту ошибку?

Только на legacy-входах, где по-прежнему выполняется исходный алгоритм. Входы segwit следуют BIP143 и хешируют нулевые байты, а входы Taproot по BIP341 полностью отвергают этот случай, поэтому биткоины на адресах bc1 не затронуты.

Связанные термины

Еще в разделе «Транзакции и комиссии»

Читать эту страницу на английском