Глоссарий / Справочник разработчика
Bitcoin Script
Другие названия: Script.
- Что такое Bitcoin Script?
- Bitcoin Script представляет собой небольшой стековый язык, который присутствует в каждом выходе биткоина и задает условия, которые кто-либо должен выполнить, прежде чем эти биткоины можно будет снова потратить.
Монеты не отправляют людям. Они заблокированы короткой программой, и потратить их означает предоставить данные, после которых программа завершится значением «истина» на вершине стека. В языке нет циклов и рекурсии, а устаревший скрипт останавливается на 10 000 байтах и 201 операции, поэтому валидатор всегда знает, что работа завершится. И поэтому у биткоина никогда не было вышедшего из-под контроля контракта.
Как это работает
Bitcoin Script представляет собой стековую машину, которая читает слева направо и не делает ничего другого.
Вставки данных помещаются в стек; операции снимают с него свои аргументы и кладут обратно результаты. Здесь нет переменных, нет переходов назад и нет способа прочитать что-либо вне транзакции, которая проверяется. Скрипт считается успешным, когда выполнение завершается без ошибки и оставляет значение «истина» на вершине.
Две части встречаются в момент расходования. Расходуемый выход несет блокировку, которая называется pubkey script. Вход, который его расходует, несет доказательство, называемое signature script для более старых выходов или witness для выходов segwit. Они выполняются последовательно, и стек передается между ними; они никогда не объединяются в единую программу. Это разделение ввели вскоре после запуска, когда стало ясно, что тот, кто тратит выход и мог бы внедрить операторы в блокирующую часть, сумел бы переписать условия.
Самый распространенный скрипт в истории биткоина стоит прочитать целиком. Выход pay-to-public-key-hash содержит OP_DUP, OP_HASH160, хеш размером 20 байт, OP_EQUALVERIFY и OP_CHECKSIG. Тот, кто тратит, предоставляет подпись и публичный ключ. Выполнение помещает в стек оба, дублирует публичный ключ, хеширует копию до 20 байт, кладет в стек ожидаемый хеш, сравнивает оба и прерывается при их несовпадении, затем проверяет подпись по сериализации самой транзакции. Шесть шагов, и на них опирается вся безопасность устаревшего адреса.
Ограничения намеренные и точные. Устаревший скрипт или скрипт P2SH не может превышать 10 000 байт или 201 операцию, не являющихся вставками данных. Ни один элемент стека не может превышать 520 байт. Стек не может содержать более 1000 элементов. Один OP_CHECKMULTISIG не может указывать более 20 публичных ключей. Каждый предел существует для того, чтобы стоимость проверки блока оставалась ограниченной, что бы кто ни писал.
Язык расширялся дважды, когда зарезервированным кодам no-op придали реальное значение. BIP65 определил OP_CHECKLOCKTIMEVERIFY в декабре 2015 года, что позволило выходу отказываться двигаться до указанного времени или высоты. BIP112 сделал то же для OP_CHECKSEQUENCEVERIFY, который действует с блока 419 328 с июля 2016 года, добавив относительные блокировки по времени, отсчитываемые от момента подтверждения монеты. Именно благодаря этим двум опкодам вообще могут существовать каналы Lightning, эскроу с крайним сроком и схемы наследования с блокировкой по времени.
Почему это важно при покупке биткоина
Адрес, на который вы выводите средства, является типом скрипта, и этот выбор отражается на вашей следующей комиссии.
Расходование устаревшего входа pay-to-public-key-hash стоит примерно 148 виртуальных байт. Расходование входа native segwit стоит примерно 68, потому что скидка на witness, введенная BIP141, начисляет плату за данные witness по четвертной ставке, а расход taproot по пути ключа еще меньше. При комиссии 20 sat/vB эта разница составляет большую часть стоимости небольшого вывода и повторяется каждый раз, когда вы перемещаете биткоины. Там, где биржа позволяет выбрать формат адреса для вывода, выбор современного формата представляет собой постоянную скидку.
Скрипт также лежит в основе того, чем на самом деле является хранилище с мультиподписью. Схема 2-из-3 представляет собой скрипт, в котором указаны три публичных ключа и требуются две подписи, а вопрос о том, может ли конкретное устройство честно показать и подписать такой скрипт, напрямую рассматривается в наших обзорах аппаратных кошельков. То же верно для любого плана наследования, построенного на блокировке по времени: биткоины можно вернуть, только если у кого-то еще остался скрипт, и поэтому дескрипторы выходов, то есть обычная текстовая инструкция для его восстановления, должны входить в вашу резервную копию рядом с сид-фразой.
Одно практическое предупреждение. Когда платформа отказывается отправлять средства на адрес, который вы вставили, причина почти всегда в том, что ее код вывода не может построить этот тип скрипта, а не в том, что ваш адрес неверен. Проверяйте любой незнакомый формат адреса небольшой суммой, прежде чем перемещать значимый для вас баланс.
Ошибка на 184 млрд биткоинов и опкоды, которые Сатоши отключил
15 августа 2010 года в блоке 74 638 содержалась транзакция, создавшая 184 467 440 737,09551616 биткоина, разделенных на два выхода примерно по 92,2 млрд каждый.
Проверка того, что выходы транзакции не превышают ее входы, использовала знаковую арифметику фиксированной ширины, и выходы, достаточно большие, чтобы переполнить эту арифметику, в сумме давали отрицательное число, поэтому проверка проходила. Исправленный клиент появился примерно через пять часов, и честная цепочка обогнала плохую на высоте 74 691. Эти монеты никогда не существовали в цепочке, которой пользуются все.
Этот эпизод вместе с семейством связанных ошибок в строковых и арифметических операциях стал причиной того, что пятнадцать опкодов отключены навсегда: OP_CAT, OP_SUBSTR, OP_LEFT, OP_RIGHT, OP_INVERT, OP_AND, OP_OR, OP_XOR, OP_2MUL, OP_2DIV, OP_MUL, OP_DIV, OP_MOD, OP_LSHIFT и OP_RSHIFT. Транзакция, в скрипте которой есть хотя бы один из них, недействительна независимо от того, выполняется он или нет. Отключение было грубым инструментом, примененным в условиях нехватки времени, и отмена его части является текущей работой: BIP347 предлагает вернуть OP_CAT внутри tapscript, где новые ограничения делают злоупотребление им намного более трудным.
Bitcoin Script vs tapscript
Tapscript представляет собой Bitcoin Script с переписанными правилами, и он применяется только внутри расхода по пути скрипта taproot. BIP342 отменил как предел размера скрипта в 10 000 байт, так и предел в 201 операцию, отключил OP_CHECKMULTISIG и OP_CHECKMULTISIGVERIFY и добавил вместо них OP_CHECKSIGADD, чтобы политики с мультиподписью можно было проверять пакетами. Проверки подписей измеряются, а не считаются: каждый вход получает бюджет в 50 плюс сериализованный размер его witness, и каждая выполненная проверка подписи расходует из него 50. Та же стековая машина, другой учет.
Bitcoin Script vs pubkey script
Bitcoin Script является языком; pubkey script представляет собой одну программу, написанную на нем. Выход содержит pubkey script, который является блокировкой. Вход, который его расходует, содержит signature script или witness, которые являются ключом. И то и другое является Bitcoin Script, и называть любое из них просто «скриптом» служит самым частым источником путаницы при чтении сырой транзакции, потому что две половины проверяются отдельно и только одна из них была зафиксирована при получении монет.