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

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

OP_DUP

Что такое OP_DUP?
OP_DUP копирует верхний элемент стека, чтобы его можно было использовать дважды, и поэтому стандартный скрипт pay-to-public-key-hash может и вычислить хеш вашего публичного ключа, и проверить подпись по нему.

Один байт, 0x76, и одна задача. В Bitcoin Script нет переменных, только стек, поэтому элемент, израсходованный одной инструкцией, исчезает до запуска следующей, и дублирование остается единственным способом использовать его повторно. Это первый из четырех рабочих опкодов в скрипте размером 25 байт, который защищал почти каждый адрес биткоина, начинающийся с 1.

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

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

Проследите шаг за шагом за расходованием в формате legacy. Данные отправителя попадают в стек как подпись, а над ней находится публичный ключ. OP_DUP создает вторую копию ключа. OP_HASH160 заменяет копию ее дайджестом размером 20 байт. Выход добавляет в стек зафиксированные 20 байт, OP_EQUALVERIFY расходует оба и прерывает весь скрипт при любом несовпадении, а OP_CHECKSIG остается с исходным ключом и подписью, то есть ровно с тем, что ему нужно. Пять шагов, без ветвлений, без циклов и с фиксированной стоимостью каждый раз.

Опкод учитывается в двух пределах, ничего дорогого при этом не делая. Он является одной из 201 рабочих инструкций, которые может содержать скрипт до Taproot, а создаваемая им копия учитывается в лимите 1000 элементов во всех стеках. Ни то, ни другое не важно при расходовании с одним ключом, и оба важны в скрипте, который дублирует элементы внутри цепочки условий без циклов.

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

Посмотрите на любую транзакцию, которая расходует адрес, начинающийся с 1, и скрипт выхода начнется с OP_DUP. Обозреватели блоков печатают его как первый токен в представлении ассемблера.

Интереснее то, где он выполняется, не появляясь. Нативный выход SegWit с одним ключом не содержит логики вообще, только байт версии и хеш размером 20 байт, но BIP-141 предписывает узлу построить классический шаблон из этого хеша и все равно его выполнить. Поэтому опкод по-прежнему срабатывает при каждом расходовании P2WPKH в сети и нигде не появляется в блоке. Поведение сохраняется, а четыре весовые единицы, которые раньше стоил этот байт, платить не нужно.

Выходы с хешем скрипта и расходования по ключевому пути Taproot его полностью пропускают. Выход P2SH сравнивает хеш напрямую, а расходование по ключу Taproot проверяет подпись по ключу выхода без участия скрипта. Это наименьшая возможная иллюстрация того, что на самом деле сделали SegWit и Taproot: не столько новые возможности, сколько те же проверки, организованные так, чтобы цепочке приходилось нести меньше байт для их получения.

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

Почему скрипту вообще нужно что-то копировать?

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

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

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

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