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

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

OP_CHECKSIG

Что такое OP_CHECKSIG?
OP_CHECKSIG снимает со стека публичный ключ и подпись и проверяет, что подпись покрывает эту транзакцию; именно эта проверка на деле доказывает, что биткоины принадлежат вам.

Почти каждый потраченный биткоин прошел через этот единственный опкод, байт 0xac. Он строит дайджест транзакции в соответствии с байтом sighash, приклеенным к концу подписи, проверяет подпись по публичному ключу и кладет в стек true или false. Если он кладет false, расход не происходит, и это и есть все, что означает владение биткоином в коде.

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

OP_CHECKSIG снимает со стека два элемента, сначала публичный ключ, а под ним подпись, и затем выполняет три отдельные задачи, которые обычно сводят к одной.

Сначала он решает, что было подписано. Последний байт подписи не является частью подписи: это флаг, указывающий, какие части транзакции покрыл дайджест. Подавляющее большинство подписей использует значение 0x01, которое означает все входы и все выходы, поэтому изменение любой части транзакции после подписания делает ее недействительной. Рецепт построения этого дайджеста заменяли дважды: BIP-143 для расходов SegWit версии 0 и снова BIP-341 для Taproot, оба раза, чтобы стоимость хеширования не росла как квадрат размера транзакции.

Во-вторых, он проверяет кодировку, и биткоин здесь необычно строг. Подпись legacy должна быть корректной в DER, не более 72 байт включая байт флага, со значением S в нижней половине порядка кривой. Строгое правило кодировки появилось как BIP-66 в июле 2015 года, и переход осиротил шесть блоков за полдня, потому что несколько крупных пулов строили блоки на заголовках, которые не проверяли. Это по-прежнему самое ясное доказательство того, что майнинг и валидация являются разными задачами.

В-третьих, он проверяет. Расходы legacy и расходы SegWit версии 0 используют ECDSA над secp256k1. Tapscript вместо этого использует подпись Schnorr из 64 байт по BIP-340, требует, чтобы неудачная проверка клала в стек пустой элемент, а не что-либо иное, и списывает с бюджета скрипта 50 весовых единиц за каждую проверенную подпись.

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

OP_CHECKSIG закрывает почти каждый существующий скрипт. Выход legacy заканчивается им, нативный расход SegWit с одним ключом использует тот же шаблон с тем же последним опкодом, хотя эти байты никогда не появляются в блокчейне, а скрипты обязательств Lightning заканчиваются им после ветвей блокировки по времени и отзыва.

Исключение стоит знать, когда вы смотрите обозреватель блоков. Расход Taproot по пути ключа не выполняет никакого скрипта: узел проверяет одну подпись напрямую по ключу из 32 байт в выходе. Там нет ассемблера для отображения и нет опкода, на который можно указать, и именно поэтому этот тип расхода является самым дешевым и самым приватным из доступных, и поэтому адрес bc1p, который тратит только его владелец, выглядит в блокчейне так же, как любой другой.

OP_CHECKSIG vs OP_CHECKSIGADD

OP_CHECKSIGADD существует потому, что OP_CHECKSIG нельзя подсчитать. В скрипте с несколькими участниками нужно знать, сколько из предъявленных подписей оказались действительными, и старая конструкция решала это одним опкодом, который разом поглощал целый список ключей и подписей. Tapscript заменил его опкодом, который проверяет одну подпись и прибавляет единицу к накопительному итогу в стеке, так что политика 2-из-3 превращается в короткую последовательность, заканчивающуюся сравнением с 2. Изменение не косметическое: подсчет подписей по одной и позволяет проверять подписи Schnorr пакетами, а пакетная проверка и дает скорость валидации Taproot.

Не путать с

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

Почему у подписи биткоина в конце есть лишний байт?

Этот байт является флагом sighash, и он сообщает проверяющему, какие части транзакции покрыла подпись. Обычное значение покрывает все входы и все выходы, поэтому после подписания в транзакции нельзя изменить ничего.

Использует ли платеж Taproot OP_CHECKSIG?

На обычном пути нет. Расход Taproot по пути ключа проверяет одну подпись Schnorr по ключу выхода, не выполняя никакого скрипта, поэтому опкод вообще не появляется. Расходы по пути скрипта его используют, в форме Tapscript, которая принимает подписи из 64 байт.

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

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

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