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

Глоссарий / Справочник разработчика

OP_EQUAL

Что такое OP_EQUAL?
OP_EQUAL сравнивает два верхних элемента стека побайтово и помещает результат true или false; это последний опкод в любом выходе pay-to-script-hash.

Байт 0x87 выполняет единственное сравнение, которое биткоину действительно нужно: идентичны ли эти два набора байтов? Сравнение идет по сырым байтам, а не по числам, поэтому в языке есть отдельный опкод для арифметического равенства. Любой платеж, который вы когда-либо отправили на адрес, начинающийся с 3, завершает свой скрипт этой одной инструкцией.

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

Со стека снимаются два элемента, а возвращается один: один байт 0x01, если они совпадают, или пустой элемент, если нет. Биткоин считает пустой элемент ложью, поэтому результат может проверить все, что идет дальше.

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

Интересное свойство в том, чего он не делает: он оставляет результат, а не действует на него. Скрипт завершается успешно только тогда, когда оставшийся на вершине элемент истинен, поэтому скрипт, который заканчивается этим опкодом, задает вопрос и позволяет результату быть ответом. Правило cleanstack в Bitcoin Core добавляет, что ничего другого остаться не может, а для расхода хеша скрипта это означает ровно одно истинное значение и ничего больше.

Эта последняя деталь важнее, чем кажется. Pay-to-script-hash не является общим правилом о хешированных скриптах; это правило об одном точном шаблоне из 23 байт: опкод хеширования, вставка данных на 20 байт и этот опкод в конце. Если записать ту же логику с помощью объединенной формы с проверкой, особый режим не применяется, скрипт погашения никогда не извлекается и не выполняется, а выход ведет себя как обычная хеш-головоломка, которую может потратить любой, кто угадает прообраз.

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

Любой неистраченный выход на адресе, начинающемся с 3, показывает в обозревателе блоков ту же сборку из трех элементов, заканчивающуюся здесь. Так же выглядит и любой вывод обернутого SegWit, который когда-либо отправляла вам биржа.

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

OP_EQUAL vs OP_EQUALVERIFY

OP_EQUALVERIFY представляет собой OP_EQUAL со встроенной проверкой. Байт 0x88 выполняет то же сравнение, а затем немедленно прерывает скрипт, если ответ ложен, и не оставляет на стеке ничего, если сравнение успешно. Выбор между ними зависит от того, что идет дальше. Используйте простую форму, когда сравнение является окончательным ответом скрипта, как в pay-to-script-hash. Используйте форму с проверкой, когда сравнение является одним условием среди нескольких и выполнение должно продолжаться, как в шаблоне legacy с одним ключом перед проверкой подписи. Форма с проверкой также экономит один байт по сравнению с записью сравнения и отдельной инструкции проверки, что имело гораздо большее значение, когда каждый байт скрипта находился в части транзакции без свидетеля, по четыре весовые единицы на байт.

Не путать с

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

В чем разница между OP_EQUAL и OP_EQUALVERIFY?

Простая форма оставляет на стеке true или false, чтобы их прочитало что-то другое, а форма с проверкой немедленно прерывает скрипт, если два элемента различаются. Pay-to-script-hash использует простую форму, потому что сравнение является окончательным ответом скрипта.

Он сравнивает числа или байты?

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

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

Еще в разделе «Справочник разработчика»

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