Перейти к содержанию

Bitcoin Script: стек и условия расходования

Адрес библиотеки позволяет создать выход, но право его дальнейшего расходования определяется условием. Bitcoin Script описывает такие условия в ограниченной стековой модели. Рассмотрим небольшой исторический шаблон, чтобы увидеть, как данные подписи сопоставляются с разрешённым ключом. Этот урок не предлагает писать произвольный скрипт для реальных средств.

У нас есть выход на 30 000 сатоши, полученный библиотекой. Политика его расходования требует подходящую подпись. Мы разбираем операции вручную; интерпретатор, узел и проверочные программы не запускаются.

Стек и инструкции

Стек хранит значения, к которым инструкции обращаются в определённом порядке. Операция может добавить элемент, скопировать вершину, вычислить хеш или проверить отношение. В отличие от привычной функции JavaScript, скрипт не получает произвольный объект заказа с полями courseId и paid. Его вход и контекст задаются транзакционными правилами.

Исторический P2PKH-шаблон можно представить так:

OP_DUP OP_HASH160 <expectedKeyHash> OP_EQUALVERIFY OP_CHECKSIG

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

Ключ здесь проверяется дважды по разным свойствам: подходит ли его отпечаток условию и подходит ли подпись этому ключу и сообщению. Корректная подпись посторонним ключом недостаточна. Правильный ключ с подписью другого сообщения также недостаточен. Именно сочетание условий даёт смысл разрешённого расходования.

Ручной разбор

Представим исходный стек как [signature, publicKey], где правый элемент — вершина. После OP_DUP появляется ещё один экземпляр ключа. После OP_HASH160 на вершине остаётся отпечаток копии. Затем добавляется ожидаемое значение и производится сравнение с обязательным успехом.

Этап Смысл проверки
Дублирование Сохранить ключ для последующей подписи
Хеширование Получить значение нужного формата
Сравнение Установить соответствие условию выхода
Проверка подписи Установить разрешение сообщения

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

Поменяем открытый ключ. Сравнение хеша не проходит, даже если подпись математически корректна для нового ключа. Поменяем сумму защищённого выхода новой транзакции. Ключ остаётся тем же, но подпись больше не соответствует новому сообщению при выбранном режиме. Оба отказа полезны: они защищают разные границы.

Скрипт не хранит состояние сайта

Скрипт проверяет расходование в установленном контексте. Он не обращается по HTTP к библиотеке, не читает базу заказов и не узнаёт, закончился ли курс. Нельзя написать условие «разрешить, если пользователь оплатил subscription=true в нашем PostgreSQL», ожидая, что узлы получат одинаковый ответ от внешнего сервера.

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

В библиотеке коммерческое право чтения остаётся серверной записью. Скрипт защищает деньги, а приложение решает, какой счёт они оплачивают. Даже если условие требует две подписи сотрудников, оно не сообщает номер урока или условия возврата. Эти связи сохраняются в документах проекта.

Разные виды расходования

Разобранный P2PKH-шаблон выбран за наглядность. Современный выход SegWit или Taproot имеет другой способ размещения программы и данных свидетеля. Нельзя буквально перенести все исторические поля в новый формат. Тип предыдущего выхода определяет путь проверки.

P2SH позволяет выходу обязаться относительно скрипта, который раскрывается при расходовании. P2WSH использует свидетеля и другое обязательство. Taproot добавляет путь ключа и предусмотренные пути скрипта со своими правилами. В следующих уроках рассмотрим различия; сейчас важно понять, что адрес относится к конкретному семейству условий.

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

Ошибки, которые скрывает короткий пример

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

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

Для нашего досье результат прост: условие выхода описывается отдельно от данных, которыми его удовлетворяют. Разрешённый ключ определяется предыдущим выходом; подпись зависит от сообщения новой транзакции. Внутренний серверный флаг не участвует в сетевой проверке сам по себе.

Сумма и контекст условия

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

Если сайт библиотеки временно недоступен, сетевое условие расходования не начинает обращаться к его резервному домену. Для нашего счёта сохраняется прежний скрипт. Восстановление сайта возвращает прикладное сопоставление заказа, тогда как восстановление подписанта возвращает возможность выполнить условие выхода. Эти два результата следует описывать отдельно в процедуре аварии.

Набор исторических инструкций приведён в справочнике Bitcoin, а современные правила свидетеля — в BIP 141. Далее разделим подпись и идентификатор транзакции в SegWit, сохранив ту же модель расходования UTXO.

Оглавление серии