Что такое segregated witness

Обновлено: 07.07.2024

SegWit (сокращенная форма от Segregated Witness) – это обновление протокола Блокчейн, которое изменяет способ хранения данных. Простыми словами это способ, позволяющий ускорить пропускную способность сети Блокчейн, тем самым делая ее более привлекательной для оплаты товаров и услуг криптовалютой. Питер Вюлле – разработчик SegWit, впервые представил эту идею на конференции Scaling Bitcoin в декабре 2015 года. Затем SegWit был активирован на Litecoin 10 мая 2017 года, а 23 августа 2017 года – на Bitcoin.

Segregated Witness для чайников

Масштабируемость биткоина является одной из его главных проблем, над решением которой активно работают. Одним из представителей этих решений является, например, технология Lightning network, но ее реализация пока что не представляется возможной ввиду некоторых уязвимостей. Другое решение — Segregated Witness также направлено на повышение масштабируемости, но ко всему прочему решает еще и целый ряд проблем, включая ту самую уязвимость, мешающую реализации лайтнинга. В этой статье мы рассмотрим основные преимущества Segregated Witness, а также опишем механизм его работы.

img

Segregated witness, или как многие его называют SegWit, это софт-форк, описанный в серии BIP'ов (141, 142, 143, 144 и 145), главной целью которого является оптимизация структуры транзакций и блоков с помощью вынесения подписей (то, что называют 'scriptSig', 'witness' или же 'unlocking script') из транзакции в отдельную струтуру. Это не только позволяет уменьшить размер транзакций, делая блоки более вместительными, но и решает проблему их "изменяемости" (transaction malleability, именно об этой уязвимости мы и говорили выше), что очень важно для технологий наподобие платежных каналов или лайтнинга, пологающихся на строение транзакции биткоина.

So what is the problem?

Картинки по запросу segregated witness medium

Так если все так хорошо, в чем же проблема? Обновление имеет немало противников в сети, так как несмотря на все очевидные преимущества, оно имеет и свои слабые стороны. Рассмотрим некоторые из аргументов против.

  • Так как segwit является софт-форком, обновлены будут далеко не все клиенты, а значит в сети будут находится одновременно два вида UTXO, и такие важные изменения как устранение уязвимости id транзакций и хеширование за линейное время не будут применены к не сегвитовским выходам, а значит сеть все еще будет уязвима к атакам, основанным на изменяемости id транзакций, а также к проблеме квадратичного времени хеширования.
  • Segwit может уменьшить безопасность сети. Количество нод, проводящих полную валидацию, сильно уменьшится, так как только принявшие segwit смогут проверять witness часть транзакций.
  • Segwit не может быть отменен. Если его отменить и откатить все изменения обратно, все segwit-выходы станут доступными каждому.
  • Segwit пытается решить все проблемы сразу и, как следствие, огромное количество кода изменено. Это усложняет дальнейшую работу и увеличивает вероятность появления багов, которые будет сложнее устранить.

Conclusion

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

Что такое SegWit ?

Многие приветствовали Сегвит, как долгожданное решение проблемы масштабирования Биткоина. Максимальный размер блока в основном протоколе составляет 1 МБ, что ограничивает количество транзакций, которые Биткоин может обрабатывать за секунду. Для примера, Visa обрабатывает 1000 транзакций за секунду, а Биткоин примерно 3. Это мешает Биткоину стать широко используемой платежной системой.

Сегвит блокирует транзакционную податливость, удаляя информацию подписи (иначе известную как информация о свидетеле), и сохраняет ее за пределами базового блока транзакций. При этом подписи и скрипты могут быть изменены без влияния на идентификатор транзакции.

SegWit представила новую концепцию – «вес блока»

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

Таким образом, SegWit не увеличивает ограничение размера блока, а позволяет включить больше транзакций в пределах блоков 1 МБ. Ключ 4MБ включает в себя отдельные данные свидетелей, которые технически не составляют часть базового блока транзакций 1 МБ.

Преимущества протокола Сегвит:

  • Третье лицо не может изменить подпись транзакции. Это дает возможность внедрения новых смарт-контрактов.
  • Увеличение пропускной способности сети Блокчейн, благодаря уменьшению размера транзакций. Количество информации, передаваемой во время транзакции, остается неизменным. Это возможно из-за перемещения подписи данных за пределы блока.
  • Снижение начисления комиссионных сборов. Из-за роста количества обрабатываемых транзакций за секунду, они станут дешевле.

Поддержка протоколов второго уровня

Еще один большой шаг вперед, сделанный SegWit, заключается в том, что он поддерживает разработку протоколов второго уровня. Сегвит сделал любую функцию, которая основывалась на неподтвержденных транзакциях, менее рискованной и удобной в проектировании.

Активация SegWit также способствовала развитию работы над другими функциями, такими как MAST (что позволяет создавать более сложные Биткоин-смарт-контракты), сигнатуры Schnorr (что позволит повысить производительность транзакций) и TumbleBit (анонимная сеть верхнего уровня).

Не все счастливы

Далеко не все в сообществе Bitcoin уверены, что SegWit – это решение, которое улучшит работу сети. Ведь количество пользователей и транзакций будет расти, и даже блок в 2 МБ в дальнейшем будет маленьким для потребностей Блокчейн системы.

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

Что такое Segregated Witness?


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

Для решения проблемы масштабируемости Segregated Witness подразумевает извлечение подписи транзакции и помещение ее в отдельную структуру данных. Когда из транзакции удаляется подпись, размер транзакции уменьшается. Следовательно, каждая транзакция уменьшается приблизительно на 47%. Таким образом, блок, не меняя своего размера, сможет вместить почти вдвое больше транзакций.

SegWit также принесет пользу держателям «полных нод», поскольку может уменьшить количество данных, необходимое для хранения на жестких дисках. Другими словами, Segregated Witness позволит сократить требования для запуска полной ноды и время, необходимое для синхронизации с сетью.

Перспективы SegWit

Несмотря на очевидные преимущества, внедрение приложения движется медленно. Только 14% транзакций использовали новый формат.

Основная причина в том, что многие кошельки еще не добавили поддержку SegWit. Некоторые крупные имена, такие как Trezor, Ledger, Electrum и Kraken, уже сделали это. Coinbase – крупнейший поставщик кошельков по количеству транзакций – работает над этим, и ожидается, что он начнет обновление в начале 2018 года. И кошелек, связанный с самой популярной полноразмерной версией Bitcoin, Bitcoin Core, как ожидается, выведет SegWit в первом квартале 2018 года.

Основной код Биткоина, который также делает корректировки, совместимые с SegWit, может привести к повышению производительности, как при использовании, так и при проведении дополнительных экспериментов. Bitcoin Core поддерживает список на своем веб-сайте предприятий и проектов, работающих над интеграцией SegWit – было развернуто 19 реализаций, а еще 90 готовы к работе.

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

Какие форматы бывают у биткоин-адресов?


Из каких частей состоит биткоин-адрес в формате legacy?

Legacy-адреса уникальны, обычно состоят из 26-35 символов и представляют собой 160-битные хэши открытого ключа ECDSA ключевой пары. С появлением SegWit-адресов их стали называть старыми, однако изначально они были достаточно эффективным средством представления locking scripts в более удобном для пользователей виде и уменьшения рисков отправки средств на некорректный адрес.Стандартный биткоин-адрес состоит из таких частей:

  • префикс;
  • сгенерированный в результате применения к приватному ключу алгоритмов SHA256 и RIPEMD публичный ключ;
  • контрольная сумма.

Почему в биткоин-адресах бывает разное количество знаков?

Если при преобразовании приватного ключа в начале результата появились нули, в строку биткоин-адреса в формате legacy они не включаются, и тогда он сокращается на соответствующее количество знаков. Поэтому биткоин-адрес может состоять не из 34, но теоретически даже из 20 символов.

Как зашифрованы части legacy-адреса?

Все части биткоин-адреса в формате legacy зашифрованы с защитой от опечаток по системе кодирования Base58Check. В основе кода лежит латинский алфавит. Вы никогда не увидите в таком биткоин-адресе символы, которые легко спутать между собой (знаки плюс и минус, косая черта, ноль, прописные буквы “o” и “i”, строчная “L”). Согласно системе Base58Check в них применяются только следующие 58 символов:

Что такое биткоин-адрес в формате P2SH?

P2SH-адреса (Pay to script hash) появились в предложении по улучшению биткоина BIP-0016 в январе 2012 года благодаря главному научному сотруднику Bitcoin Foundation Гэвину Андресену. Они имеют ту же структуру, что и legacy-адреса, но начинаются с цифры 3.Такие адреса предполагают, что при переводе средств получатель должен иметь скрипт, подходящий к скрипту хеша. Эта особенность позволяет снижать комиссию за перевод биткоинов отправителем, перекладывать комиссионные затраты на получателя и создавать адреса с мультиподписью.

Технология P2SH может разрешить использование средств любым пользователем или, наоборот, запретить для всех. Важно помнить, что биткоин-адреса в формате P2SH поддерживают SegWit, но не являются его нативным решением. Не поддерживающие SegWit криптокошельки могут проводить SegWit-транзакции благодаря механизмам P2WPKH-в-P2SH и P2WSH-в-P2SH.

Что такое биткоин-адрес в формате SegWit?

  • легко читаемой человеком части,
  • разделителя (1),
  • данных и контрольной суммы.

Если при введении адреса было допущено до четырех ошибок, контрольная сумма, входящая в Bech32-адрес, не сойдется. Благодаря примененному в решении коду Боуза-Чоудхури -Хоквингема (БЧХ-коду) ошибки будут автоматически исправлены.
При записи Bech32-адрес применяются следующие 32 символа:

Какие плюсы и минусы использования Bech32-адресов?

Можно ли переводить биткоины с legacy-адреса на SegWit-адрес?

В обратном направлении, с bc1-адреса на legacy-адрес, средства должны поступить без проблем.

Segregated witness benefits

Теперь, когда мы разобрались с технической частью, рассмотрим основные преимущеста segregated witness.

Transaction malleability

Одной из самых важных проблем, которые решает segwit является "изменяемость" транзакций, а если точнее, то их ID, являющиеся хешами. Разберемся немного подробнее.

В традиционном случае подписи, находящиеся внутри транзакции во входах, могут быть изменены третьей стороной без их инвалидации. Это позволяет изменять ID транзакции, являющийся ее хешем, не меняя никаких "фундаментальных" полей вроде входов/выходов/количества средств. Таким образом транзакция все еще валидна, однако теперь имеет другой ID, что создает возможность для разного рода атак, например denial-of-service.

Segwit решает эту проблему, т.к все подписи находятся снаружи транзакции, а значит не хешируются и их изменение никак не повлияет на ID транзакции. Также вводится отдельный идентификатор wtxid — он хеширует не только транзакцию но и всю witness часть, так что если транзакция передается без witness данных, то txid равен wtxid.

Решение данной проблемы позволяет создавать цепочки неподтвержденных транзакций без какого-либа риска — очень важное свойство для таких протоколов как Lightning Network.

Network and Storage Scaling

Witness данные зачастую составляют самую большую часть транзакции. В скриптах наподобие multisig'a они могут занимать до 75% места используемого транзакцией. Благодаря segwit'y передача подписей становится опциональной — нода запрашивает их только если собирается проводить валидацию транзакции. SPV (simple payment verification) клиенты или ноды, не поддерживающие сегвит, в таком случае могут не загружать лишние данные, экономя место на диске.

Block size increase and lower transaction fees

Segwit транзакции обходятся дешевле, нежели традиционные за счет скидки на хранение witness данных. Если быть точнее, то было изменено само понятие "размера" для segwit транзакций. Вместо обычного размера для них было введено понятие "виртуального размера" (virtual size) — все данные, хранящиеся в "witness", учитываются с коэффицентом в 0.25, что также позволяет разместить в блоке больше транзакций. Рассмотрим на примере.

Пусть у нас есть традиционная транзакция размером в 200 байт. В блок размера 1 МB поместится 5000 таких. Теперь возьмем ее segwit эквивалент, где примерно 120 байт это witness данные. Тогда ее vsize = 80 + 0.25 * 120 = 110 и теперь уже 9090 таких транзакций влезут в блок. Также при комиссии, допустим, в 40 satoshi/byte для 1ой транзакции мы получим комисси в 8000 сатоши, а для 2ой 4400 сатоши, что практически в два раза меньше.

Script Versioning

Как вы уже могли заметить, каждый locking script имеет байт, отвечающий за версию скрипта. Использование версий позволяет вносить дополнения и изменения (изменения в синтаксисе, новые операторы и тд.) в виде софт-форков.

Signature Verification Optimization

Segregated Witness также оптимизирует работу алгоритмов с подписями (CHECKSIG, CHECKMULTISIG и тд.). До segwit'a количество хеш-вычислений увеличивалось квадратично от количества подписей, в то время как в обновлении сложность алгоритма понижена до O(n).

Linear versus quadratic

How it works

Before we begin

Похожее изображение

Поле PubKey script (далее scriptPubKey) в выходах это то, что называют locking script. Оно нужно для того, чтобы только владелец адреса, на который перечисляются срества, смог воспользоваться этим выходом. Поле Signature Script (далее scriptSig) еще называют unlocking script — оно "отпирает" locking script, предоставляя доказательство владения адресом.

Подробнее о транзакциях, а также о работе запирающего и отпирающего скрипта можно почитать здесь.

Backward compability

На самом деле, Segregated Witness меняет не только строение транзакции, но и ее выходы. Это, однако, не значит, что в одной и той же транзакции не могут быть потрачены как традиционные UTXO (unspent transaction outputs), так и сегвитовские — просто первые будут ожидать "доказательства" внутри входа (поле scriptSig), а вторые — снаружи.

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

Examples

Pay-to-Witness-Public-Key-Hash

Теперь давайте взглянем на примеры транзакций и на то, как они изменятся с Segregated Witness. Мы начнем со стандартной Pay-to-Public-Key-Hash (P2PKH) транзакции.

Нас интересуют выходы, а именно их поля "scriptPubKey". Рассмотрим типичный locking script:

C Segregated Witness он будет выглядеть так:

Как видите, сегвитовский выход намного проще традиционного — он состоит из двух значений, которые будут помещены на стэк исполнения скрипта. Как мы уже упомянули ранее, для старых версий клиента биткоина этот выход будет виден как доступный любому, так как он не требует подписи. А вот для обновленного клиента первое число интерпретируется как номер версии, а второе как аналог запирающего скрипта (witness program). На самом деле, здесь должен быть использован хеш сжатого публичного ключа, об этом мы расскажем немного позже.

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

Однако, чтобы потратить сегвитовский выход, транзакция должна иметь пустое поле sriptSig и содержать все подписи в отдельном месте:

Warning

Несмотря на то, что традиционные клиенты могут обрабатывать сегвитовские транзакции (напомню, что их выходы выглядят как доступные всем для старых клиентов), они не могут тратить их выходы, так как они просто не знают, как это сделать: кошелек старого типа попытается потратить сегвитовский выход с пустой подписью, однако эта транзакция на самом деле не валидна (ноды, имеющие Segregated Witness, не пропустят такую транзакцию). Это значит, что отправитель должен знать, поддерживает ли кошелек получателя segwit или нет, чтобы создавать выходы нужного типа.

Начиная с BIP 143 выходы должны быть созданы с помощью хеша сжатого публичного ключа. Если вы создадите выход используя обычный адрес или несжатый публичный ключ, этот выход будет неиспользуемым.
Pay-to-Witness-Script-Hash

Следующим очень важным типом транзакции является P2SH — он позволяет отправлять транзакции на хеш скрипта вместо хеша публичного ключа (обычный адрес биткоина). Чтобы потратить выход P2SH транзакции нужно предоставить скрипт (его называют redeem script), хеш которого совпадает с хешем скрипта на который отправлены средства, а также подписи/пароли/что-то еще в зависимости от скрипта. Используя такой подход можно отправлять биткоины на адрес, защищенный способом, о котором нам ничего не известно, а также сильно экономить место — в случае, например, кошелька с мультиподписью (multisignature wallet) locking script был бы действительно большим, если бы мы хранили все "замки" полностью, а не только их хеш.

Итак, рассмотрим в качестве примера кошелек с мультиподписью, требующий наличия 2ух подписей из 5. В традиционном виде locking script выхода P2SH транзакции выглядит так:

Чтобы потратить его, нужно предоставить redeem script, определяющий условие мультиподписи 2 из 5, а также 2 подписи и все это должно находится во входе транзакции:

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

Locking script выхода:

Опять же, как и в случае с P2PKH транзакцией полученный скрипт намного проще. Здесь 1ое значение это номер версии, а второе — 32 байтный SHA256 хеш redeem script'a (witness program). Эта хеш-функция была выбрана для того, чтобы как-то отличать witness program P2WPKH от оной для P2WSH по длине хеша (32 байта SHA256 и 20 байт RIPEMD160(SHA256(script))).

Транзакция, использующая этот выход:

Embedding Segregated Witness inside P2SH

Итак, мы убедились, что использование Segregated Witness имеет свои преимущества, однако для приведенных выше примеров и отправитель и получатель должны быть обновлены, что возможно далеко не всегда. Рассмотрим, например, такую ситуацию:

В таком случае Боб может создать P2SH адрес, содержащий в себе segwit скрипт. Для Алисы он будет виден как самый обычный P2SH адрес и она сможет без каких либо проблем перевести на него средства, а Боб сможет потратить этот выход используя сегвит-транзакцию и получив скидку на комиссию (о новой метрике установления комиссии для сегвит транзакций мы расскажем ниже).

Таким образом оба типа сегвит-транзакций — P2WSH и P2WPKH могут быть реализованы внутри P2SH.

P2SH(P2WPKH)

Для использования P2WPKH транзакции внутри P2SH Бобу нужно создать witness program из своего публичного ключа. Затем результат нужно хешировать и преобразовать в P2SH адрес:

Создаем witness program:

Как обычно — 1ое число это версия и 2ое это 20 байтный хеш публичного ключа. Полученный скрипт затем хешируется SHA256 и потом RIPEMD160, выдавая очередной 20 байтный хеш.

HASH160 от witness program P2WPKH:

И преобразовываем в адрес:

Locking script выхода отправленного на этот адрес будет выглядеть как скрипт для обычного P2SH адреса:

Теперь рассмотрим как Боб может потратить этот выход:

Сначала предоставленный нами redeem script (в нашем случае это witness program) будет хеширован и, если он равен хешу, указанному в locking script'e, то он будет выполнен и будут проверены подписи в поле "witness".

P2SH(P2WSH)

Точно также любой P2WSH скрипт может быть реализован внутри P2SH. Возьмем multisig скрипт 2 из 5, рассмотренный ранее. Все шаги будут практически идентичны случаю P2SH(P2WPKH):

Для начала, опять же, создаем witness program:

1ое число — версия, 2ое — 32 байтный SHA256 хеш нашего скрипта мультиподписи. Далее шаги повторяются — берем HASH160 от witness program и преобразовываем в обычный P2SH адрес. Для использования выхода, отправленного на этот адрес, в scriptSig нужно записать witness program, а все подписи и полный скрипт мультисига в поле witness.

Читайте также: