Глоссарий / Справочник разработчика
Скрипт погашения
Другие названия: Redeem script.
- Что такое скрипт погашения?
- Скрипт погашения представляет собой полный контракт расходования, скрытый за выходом pay-to-script-hash: его предоставляет тот, кто тратит, в конце скрипта подписи, и его хеш вычисляют, чтобы проверить совпадение.
Определено в BIP-16.
BIP-16 позволил отправителю платить по хешу в 20 байт вместо целого контракта, и скрипт погашения является тем контрактом, который этот хеш представляет. Он должен поместиться в один элемент стека, поэтому 520 байт являются жестким потолком. Потеряйте эти байты, и ваши приватные ключи ничего не будут стоить, поэтому скрипт погашения входит в вашу резервную копию, а не в ваше программное обеспечение.
Как это работает
Скрипт погашения невидим, пока биткоины лежат на месте. Выход, в котором они находятся, содержит только хеш и шаблон, который распознает консенсус, и это правило действует по всей сети с 1 апреля 2012 года, на блоке 173 805. Никто из тех, кто платит вам, не узнает ничего об условиях, и обозреватель блоков тоже.
Раскрывается он при расходовании. Скрипт подписи помещает в стек аргументы, нужные контракту, и завершается самим сериализованным контрактом. Проверяющий узел берет последний элемент, вычисляет его хеш, сравнивает результат с хешем в выходе и только затем десериализует элемент и выполняет его как код на оставшемся стеке. Оба этапа должны пройти, и поскольку поле, переносящее его, может содержать только операции помещения в стек, сам скрипт не может протащить какое-либо поведение до того, как его проверят.
Самый распространенный скрипт погашения вовсе не является контрактом. Начиная с 2017 года кошельки, которые хотели экономии SegWit, оставаясь при этом доступными для оплаты со стороны старого программного обеспечения, обернули программу свидетеля в хеш скрипта, поэтому скрипт погашения занимает 22 байта: байт версии и хеш ключа в 20 байт, и выполнять там нечего. Миллионы адресов для вывода с бирж, начинающиеся с 3, скрывают именно это и ничего больше.
Где это видно
Bitcoin Core выдает его вам каждый раз, когда вы создаете скриптовый адрес, а его команда decodescript превращает шестнадцатеричную строку обратно в читаемый ассемблер. В дескрипторе скрипт записывается явно как sh(wpkh(...)) или sh(multi(...)), и это современный способ его фиксировать, потому что кошельки с дескрипторами появились в Bitcoin Core 0.21.0 в январе 2021 года и сделали устаревшей прежнюю привычку импортировать голые адреса.
Сценарий потери реален и конкретен. Сид-фраза восстанавливает ключи. Она не восстанавливает произвольный скрипт и не может сообщить вам публичные ключи других соподписантов, поэтому схема 2-из-3, в которой каждый участник сохранил только свою сид-фразу, является нерасходуемой. Люди теряли биткоины, имея полный набор приватных ключей и не имея записи о скрипте, в который эти ключи были собраны. Храните дескриптор вместе с каждой резервной копией сид-фразы и один раз восстановите из него на небольшую сумму, прежде чем на адресе окажется что-то, что вам было бы жаль потерять.
Еще нужно знать об ограничении по размеру. Пятнадцать сжатых публичных ключей плюс их префиксы помещения в стек и окружающие опкоды дают 513 байт, что как раз помещается; шестнадцатый уже нет. Именно этот потолок, а не какое-либо правило о мультиподписи, ограничивает скриптовый адрес пятнадцатью соподписантами.
Скрипт погашения vs скрипт свидетеля
Скрипт погашения и скрипт свидетеля занимают одно и то же концептуальное место в две разные эпохи, а разница в том, где передаются байты и чем они фиксируются. Скрипт погашения фиксируется хешем в 160 бит и передается в скрипте подписи по четыре весовые единицы на байт. Скрипт свидетеля фиксируется полным SHA-256 в 256 бит и передается в свидетеле по одной весовой единице на байт, поэтому та же политика стоит при расходовании примерно вчетверо меньше. Вложенная схема использует оба сразу: скрипт погашения является программой свидетеля в 34 байта, а скрипт свидетеля представляет собой фактический контракт. Если вы записываете резервную копию для вложенной мультиподписи SegWit, вам нужны записанными оба, а не один.