Найти тему
Про Крипто

Segregated Witness. Часть 2.2. Legacy Segwit. P2SH-P2WSH

Оглавление

В прошлый раз мы затронули тему Legacy Segwit(Nested Segwit)- промежуточного варианта использования протокола Segwit и всех его преимуществ. Напомню, что после активации Segwit сети Биткоин понадобилось некоторое время для полного принятия протокола. Не все клиенты были обновлены сразу, и некоторое время был достаточно актуален вопрос, связанный с обратной совместимостью(backward compatibility). Не обновлённые клиенты не могли отправлять средства на bech32 адреса, в силу чего возникла необходимость в промежуточном варианте. Решением стала обёртка Segwit в P2SH адреса.

Я уже рассказывал про такую обёртку для Segwit адресов типа P2WPKH: P2SH-P2WPKH. Сегодня мы рассмотрим второй тип обёртки, используемый как альтернатива для Segwit адресов типа P2WSH: P2SH-P2WSH.

Чтобы определить отличия в обработке скрипта P2WSH и его P2SH обёртки, начнём по порядку с первого.

P2WSH

Также, как и в случае P2WPKH, поле scriptSig будет пустым, а scriptPubKey содержит два элемента: 0 и 32-байтное хеш-значение witness скрипта, содержащегося в поле witness.

Добавьте описание
Добавьте описание

Аналогично с P2WPKH адресами, скрипты, связанные с адресами P2WSH, начинают обрабатываться с пары полей scriptPubKey и scriptSig, где последнее поле пустое.

Добавьте описание
Добавьте описание

Элементы, содержащиеся в scriptPubKey(0 и 32-байтное хеш-значение witness скрипта) последовательно попадают в стек.

Добавьте описание
Добавьте описание

Segwit ноды распознают P2WSH скрипт по длине хеш-значения в верхушке стека. 32-байтный хеш определяет P2WSH скрипт. Поэтому Segwit ноды смогут определить, что необходима дополнительная проверка скрипта, а именно скрипта, находящегося в поле witness. Он вместе с подписями попадает в стек. Для лучшего понимания давайте рассмотрим, как это работает, на примере скрипта, реализующего мультиподпись 2 из 3. То есть для генерации подписи нужно использовать любые два приватных ключа из трёх возможных, а для траты средств с данного адреса нужно 2 открытых ключа, соответствующих этим приватным ключам.

Добавьте описание
Добавьте описание

Вместе с подписями из witness новый полный скрипт будет выглядеть следующим образом.

Добавьте описание
Добавьте описание

Далее проверка происходит по стандартным правилам P2SH. В стек последовательно помещаются 0, все подписи, число 2, определяющее сколько нужно приватных ключей для подписания сообщения(и открытых ключей для проверки подписи), все открытые ключи и число 3, определяющее общее число доступных открытых ключей.

Добавьте описание
Добавьте описание

Выделенные красным элементы 2 и 3 определяют структуру подписи: 2 из 3. Далее выполняется опкод OP_CHECKMULTISIG, который по верхнему элементу стека 3 понимает, сколько всего используется открытых ключей в мультиподписи, и берёт из стека следующие три элемента, являющиеся открытыми ключами. Затем считывается число 2 и за ним из стека берётся ровно 2 элемента, которые являются подписями. Предполагается, что две эти подписи получены с использованием приватных ключей, связанных с двумя открытыми ключами из трёх, до этого взятых нами из стека. Таким образом, опкод OP_CHECKMULTISIG знает структуру мультиподписи(2-из-3), три отрытых ключа и две подписи. С помощью всех этих данных опкод проверяет верность рассматриваемой мультиподписи. Если результат проверки положительный, скрипт признаётся выполненным, и пользователь может потратить средства, связанные с этим входом.

P2SH-P2WSH

Теперь посмотрим, как это всё работает при использовании P2SH-P2WSH обёртки.

Добавьте описание
Добавьте описание

Аналогично стандартному скрипту P2SH, начинаем с проверки соответствия выкупающего скрипта(redeem script), содержащегося в scriptSig, хеш-значению выкупающего скрипта из scriptPubKey.

Добавьте описание
Добавьте описание

Если в scriptPubKey действительно находится хеш-значение выкупающего скрипта из scriptSig, проверка переходит в следующую стадию. Точнее, мы начинаем проверять сам выкупающий скрипт. В контексте P2SH-P2WSH выкупающий скрипт состоит из двух элементов: 0 и 32-байтного хеш-значения.

Добавьте описание
Добавьте описание

Не обновлённые ноды на этом закончат проверку данного скрипта, так как они не знают правил проверки Segwit. При этом результат проверки будет положительным в силу того, что в стеке верхний элемент не равен 0.

Segwit ноды, в свою очередь, считав верхний элемент стека: 32 байтное хеш-значение, определят, что речь идёт о P2SH-P2WSH скрипте, и продолжат работать уже с новым развёрнутым скриптом. Например, со скриптом, реализующим мультиподпись.

Добавьте описание
Добавьте описание

Дальше процесс продолжается, полностью повторяя проверку вышеописанного witness скрипта P2WSH.

Добавьте описание
Добавьте описание

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

Таким образом, такой механизм позволил не обновлённым клиентам использовать преимущества протокола Segwit во время переходного периода. Также, как и в случае с P2SH-P2WPKH адресами, P2SH-P2WSH обёртка на сегодня не так актуальна, как после активации протокола Segwit. Подавляющее большинство кошельков и сервисов обновили своё ПО и могут работать с bech32 адресами. Тем не менее, P2SH-P2WSH обёртка была интересным и своевременным решением, которое, на мой взгляд, позволило индустрии быстрее приспособиться к Segwit протоколу. Следующим важным обновлением в сети Биткоин стало внедрение подписи Шнорра и активация протокола Taproot. Но об этом мы с Вами поговорим в следующий раз. А пока на сегодня всё. Всем криптобобра и оптимизма)!