Глоссарий / Транзакции и комиссии
Изменяемость транзакций
Другие названия: Мутабельность транзакций.
- Что такое изменяемость транзакций?
- Изменяемость транзакций представляет собой недостаток, который позволял третьей стороне изменить идентификатор транзакции, не меняя того, куда ушли деньги, путем повторного кодирования содержавшихся в ней данных подписи.
Определено в BIP-66.
Платеж все равно проходил, менялось только его имя. Биткоин закрывал эту брешь поэтапно между 2015 и 2017, а SegWit завершил работу для входов, которые хранят подписи в свидетеле (witness). Устаревшие входы (legacy) остаются изменяемыми, и это еще одна причина хранить биткоины на адресе bc1.
Как это работает
Идентификатор транзакции представляет собой хеш байтов транзакции, поэтому изменение любого байта дает другой идентификатор, а в устаревшем входе подпись является одним из таких байтов.
Три вида свободы делали изменение возможным, ничего не ломая.
Первый является арифметическим. Подпись ECDSA представляет собой пару чисел, r и s, и для каждого допустимого s существует второе столь же допустимое значение: порядок кривой минус s. Любой, кто наблюдает за сетью, может поменять одно на другое, и проверка по-прежнему проходит.
Второй является кодированием. Подписи оборачивались в DER, а библиотека, на которую опирался биткоин, принимала небрежные варианты: лишние ведущие нулевые байты, неканонические маркеры длины, заполнение, которое не выдал бы ни один аккуратный кодировщик. Каждый вариант при хешировании давал другой идентификатор.
Третий является скриптом разблокировки вокруг подписи. Добавление лишнего безвредного элемента в стек оставляло результат скрипта прежним, а сериализованные байты другими.
Исправления приходили по одному уровню за раз. BIP66 сделал строгое кодирование DER правилом консенсуса на высоте 363 725, 4 июля 2015 года, активация, которую помнят в основном потому, что несколько крупных пулов строили на заголовках, которые они не проверяли, и в тот день возник форк из шести блоков. Bitcoin Core 0.11.1, выпущенный в октябре 2015 года, сделал низкие значения s правилом политики ретрансляции, позже описанным как BIP146. BIP62, попытка перечислить и запретить все оставшиеся источники, был заброшен как неосуществимый и по сей день имеет статус Withdrawn. Вопрос решил SegWit, действующий с высоты 481 824, 24 августа 2017 года: подписи перешли в свидетель, идентификатор вычисляется без свидетеля, и для входа segwit попросту не остается ничего, что можно было бы изменить.
Где это встречается
Изменяемость никогда не приводила к кражам, она приводила к ошибкам учета, и такова форма этого риска до сих пор.
Кастодиальному сервису, который отслеживал выводы по идентификатору, который он транслировал, могли показать подтвержденную транзакцию с другим идентификатором, он мог заключить, что его собственный платеж не прошел, и отправить биткоины снова. Такая схема причинила реальные убытки на биржах в 2014 году, и поэтому серьезные операторы сверяют по адресу выхода и сумме, а не только по идентификатору.
Сцепленные транзакции стали другой жертвой. Дочерняя транзакция, которая тратит неподтвержденную родительскую, называет родительскую по идентификатору, поэтому измененная родительская оставляет дочернюю навсегда неспособной к расходованию. Любой протокол, который подписывает возврат до трансляции финансирующей транзакции, а именно это и делает открытие канала Lightning, было небезопасно строить, пока идентификаторы не стали стабильными.
Для того, кто покупает и хранит, все это покрывает одна привычка. Неподтвержденный идентификатор не является фактом. Он все еще может измениться из-за изменяемости на устаревших входах, а теперь он рутинно меняется по другой причине, потому что Bitcoin Core по умолчанию ретранслирует полный replace-by-fee, и отправитель, который повышает комиссию, публикует новый идентификатор. Дождитесь подтверждения, а затем сообщайте идентификатор тому, кто его спросит.
Изменяемость транзакций vs двойная трата
Изменяемость перемещает метку; двойная трата перемещает деньги. В измененной транзакции те же биткоины приходят на тот же адрес в той же сумме, и замечает произошедшее только программное обеспечение, запомнившее старый идентификатор. При двойной трате конкурирующая транзакция отправляет эти биткоины в другое место, и одна из версий оказывается ничего не стоящей. Смешение этих двух понятий учит людей не доверять подтвержденным платежам, а это неверный урок: подтвержденный идентификатор никогда не был изменяемым, потому что изменяемость всегда действовала только пока транзакция оставалась неподтвержденной.