Opcode — отдельная инструкция Bitcoin Script, языка проверки условий расходования. Она может копировать данные или проверять подпись. Это не платёж и не закрытый ключ; значение зависит от окружающих данных и версии скрипта.
Анна хочет заплатить Петру. Кошелёк готовит транзакцию и нужные подписи, а узлы проверяют, могла ли она потратить выбранные монеты. Кошелёк — приложение или устройство для получения и отправки биткоинов. Узел — программа, которая проверяет транзакции и блоки и обменивается данными с другими участниками сети. Bitcoin Script описывает часть этих проверок. Opcode — один шаг, например проверка подписи. Для обычного платежа Анна не пишет инструкции вручную. Но узел не может поверить имени владельца или пометке «подписано»: он должен проверить условия. Корректный скрипт — лишь часть проверки всей транзакции. [1] [4]
В удобном для чтения виде можно увидеть OP_DUP или OP_CHECKSIG. Это названия инструкций для людей; в скрипте их представляют однобайтовые коды. Байт — обычная единица объёма данных. Другие части содержат данные, например открытый ключ. Открытый ключ используют для проверки подписей; его не требуется хранить в секрете. Инструкции семейства OP_PUSHDATA задают, сколько следующих байтов поместить как данные. Байты внутри этих данных не выполняются повторно как инструкции. Представьте разницу между словами «добавьте соль» в рецепте и ингредиентом, который кладут в миску. [1] [2]
Представьте стопку записок, из которой берут верхнюю. Так работает основной стек скрипта. OP_DUP копирует верхний элемент, а OP_DROP его удаляет. Выполнение OP_DUP, а затем OP_DROP на непустом стеке возвращает исходное содержимое. Вы не удвоили монеты, а лишь скопировали рабочие данные. Если нужного элемента нет, проверка может завершиться ошибкой. Порядок и точная кодировка тоже важны. [1]
OP_EQUAL берёт два верхних элемента, сравнивает их байты и заменяет результатом сравнения. OP_EQUALVERIFY немедленно завершается ошибкой при несовпадении; при совпадении продолжает без этого результата в стеке. Ни одна из этих двух операций сама не проверяет подпись. Две одинаковые копии открытого ключа может предъявить кто угодно. Чтобы установить, что кто-то мог подписать нужное сообщение, необходима соответствующая проверка подписи. [1] [4]
OP_CHECKSIG проверяет подпись по открытому ключу и сообщению, составленному из транзакции. Закрытый ключ — секретное числовое значение, с помощью которого создают такую подпись. Закрытый ключ при этом не раскрывается. Параметр sighash определяет охваченные части: не каждый режим подписывает всё. Старые скрипты и SegWit версии 0 используют алгоритм подписи ECDSA. Tapscript, правила скриптов Taproot, для обычных ключей длиной 32 байта использует другой алгоритм — Schnorr. Одного названия инструкции без этого контекста недостаточно. [1] [3]
Условие может разрешать обычное расходование или альтернативный путь восстановления. OP_IF и OP_ELSE выбирают ветвь по значению из стека, а OP_ENDIF закрывает условную часть. В Bitcoin Script нет общих программных циклов с произвольным повторением. Но нельзя игнорировать всё в невыполняемой ветви. Некоторые инструкции проверяются уже при чтении скрипта; важны их тип и версия правил. [1] [3]
CLTV, инструкция OP_CHECKLOCKTIMEVERIFY, может задать абсолютный порог, например определённую высоту блока, то есть его позицию в цепочке. CSV, OP_CHECKSEQUENCEVERIFY, совместно с правилами возраста транзакции требует относительной задержки от подтверждения расходуемого выхода. Выход — ранее полученная сумма с условиями расходования. Инструкции проверяют поля транзакции: не запускают таймер, не отправляют деньги и не заменяют подпись. В конкретном применении правильную временную блокировку нужно сочетать с остальными условиями. [7] [8] [9]
Перед чтением технического примера выясните, использует ли он старые скрипты, SegWit или Tapscript. Tapscript добавляет OP_CHECKSIGADD для объединения проверок подписей. Напротив, OP_CHECKMULTISIG при выполнении завершается ошибкой; в невыполняемой ветви эти правила его игнорируют. Названия не противоречат друг другу: среды проверки различаются. Список opcodes — не универсальный конструктор, детали которого можно бездумно переносить между форматами. [1] [3] [6]
BIP 342 резервирует семейство OP_SUCCESSx для будущих расширений Tapscript. После прохождения предшествующих проверок обнаружение такой инструкции при декодировании позволяет пропустить последующие проверки скрипта с успехом, даже в невыполняемой ветви. Случайно такой же байт внутри добавленных данных не считается. Это пространство для изменения правил, а не уже активированная защита. Условие, опирающееся на ещё не определённый будущий смысл, может не защитить средства так, как ожидает автор. [1] [3]
Full Node самостоятельно проверяет правила действительности, но может строже относиться к приёму и пересылке неподтверждённых транзакций. Например, Bitcoin Core v29.0 по умолчанию отказывается пересылать транзакции, использующие инструкцию OP_SUCCESSx в Tapscript, хотя консенсус может допускать их в блоке. Читая пример, определяйте версию, исходные данные, охват подписи и причины отказа. Понятный синтаксис сам по себе не доказывает безопасность кошелька; в обычной работе эту задачу выполняет проверенное программное обеспечение. [1] [5]
Для полной картины прочитайте эту статью вместе с Bitcoin Script, CLTV, CSV, Taproot, Bitcoin, Full Node. На эту статью также ссылаются CLTV, CSV.