Глоссарий / Транзакции и комиссии
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 является модификатором, поэтому они отвечают на разные вопросы. Базовый режим решает, какую долю стороны выходов покрывает подпись: всю, никакую или один совпадающий выход. Модификатор решает, какую долю стороны входов она покрывает: все входы или только подписываемый. Вы выбираете один базовый режим, а затем отдельно решаете, добавлять ли модификатор, поэтому байт флага у реальной подписи обычно является суммой двух, а не каким-то одним из них.