MSTR Cat

Блокчейн/Уровень IV · Глубины протокола/4.1 Script/Урок 2

Стандартные скрипты: P2PKH и P2SH

Привязка монет к ключу, а затем к хешу любого скрипта

МатериалыОбозреватель блоков (например, Blockstream.info или mempool.space)Инструмент хеширования SHA-256 и RIPEMD-160Таблица шестнадцатеричных кодовОбозреватель блоков, позволяющий просматривать сырые транзакции в hex

Любопытство

  1. Почему Bitcoin связывает монеты с хэшем, а не с самим ключом?
  2. Как четырёхстрочный скрипт проверяет и владение, и авторизацию за одно выполнение?
  3. Что сделало формат адреса P2PKH стандартным на протяжении более восьми лет истории сети?

Исследование

    Часть IPay-to-public-key-hash (P2PKH)

  1. Генезис-блок содержал только выходы Pay-to-Public-Key (P2PK). Такие скрипты помещали полный публичный ключ (в 2009 году — 65-байтовый несжатый ключ) прямо в выход, где он был виден ещё до любой траты, и делали выходы большими. P2PKH, также присутствовавший в исходном ПО 2009 года и использовавшийся для обычных платежей на адреса, вместо этого хранит 20-байтовый хеш, скрывая ключ до тех пор, пока монеты не будут потрачены.
  2. Запирающий скрипт выглядит так: `OP_DUP OP_HASH160 <hash> OP_EQUALVERIFY OP_CHECKSIG`. Выполнение начинается с данными тратящего в стеке: подпись, а над ней, на вершине, публичный ключ. Движок дублирует ключ, хеширует его как RIPEMD-160(SHA256(key)) и сравнивает результат с сохранённым хешем. Если они совпадают, `OP_EQUALVERIFY` проходит успешно; в противном случае выполнение немедленно прерывается.
  3. После успешной проверки хеша `OP_CHECKSIG` проверяет подпись ECDSA по раскрытому публичному ключу и данным транзакции. Этот двойной механизм гарантирует, что разблокировать средства может только владелец соответствующего приватного ключа. Выходной скрипт занимает в сумме 25 байт — компактная структура, ставшая основой устаревших (legacy) адресов, начинающихся с '1'.
  4. P2PKH был самым распространённым типом выхода для обычных платежей на протяжении большей части истории биткоина и оставался им ещё годы после активации SegWit в августе 2017 года на блоке 481,824, поскольку переход на нативный SegWit шёл постепенно. Его успех объяснялся простотой и совместимостью: ему не требовалось никаких обновлений консенсуса сверх исходных правил протокола. Каждая нода могла независимо проверять такие скрипты без сложного отслеживания состояния, что делало его самым надёжным типом выхода для переводов общего назначения в период раннего роста Биткоина.
  5. Формат адреса использует кодировку Base58Check, включающую четырёхбайтовую контрольную сумму для выявления опечаток. Одна неверно введённая буква почти наверняка не пройдёт проверку контрольной суммы, и кошелёк отклонит адрес. Эта избыточность сделала P2PKH удобным для пользователей, несмотря на его сугубо техническую сложность, и сократила разрыв между криптографической безопасностью и удобством для человека.
  6. Откройте обозреватель блоков и найдите любую транзакцию со входом, ссылающимся на адрес, начинающийся с '1'. Изучите поле `scriptSig`: оно содержит подпись, за которой следует публичный ключ в виде шестнадцатеричной строки. Сопоставьте этот публичный ключ с 20-байтовым хешем в `scriptPubKey` выхода, на который ссылается вход. Если применить к этому ключу SHA-256, а затем RIPEMD-160, получится сохранённый хеш, что подтверждает связь.
  7. Часть IIPay-to-script-hash (P2SH)

  8. До 2012 года для использования сложного скрипта, например мультиподписи «пять из пяти», требовалось помещать весь запирающий код прямо в выход. Из-за этого выход получался большим, и комиссию за него платил отправитель. Кроме того, публичные ключи всех участников и конкретные требования к подписанию становились видны любому, кто наблюдал за блокчейном. Отправитель должен был заранее знать точную структуру адресата, что создавало неудобства для корпоративных казначейств и бирж, которым требовались гибкие настройки безопасности.
  9. Чтобы решить эту проблему, в начале 2012 года Гэвин Андресен предложил BIP16. Он позволял выходу содержать не сам скрипт, а лишь его хеш HASH160. Выходной скрипт сократился до 23 байт — чуть меньше, чем 25 байт у P2PKH. Отправителю больше не нужно было знать условия траты: он просто платил на хеш. Вся сложность целиком перешла к тому, кто тратит монеты.
  10. Активация BIP16 в апреле 2012 года вызвала споры. Люк Дэшджуниор (Luke Dashjr) предложил альтернативу — BIP17, использовавший другой опкод и другую схему кодирования. Дискуссия о том, какое предложение принять, в сообществе разработчиков заметно накалилась. BIP16 был активирован в апреле 2012 года после того, как майнеры просигнализировали о поддержке, и стал стандартным способом упаковки сложных скриптов.
  11. Трата выхода pay-to-script-hash проходит в два этапа. Сначала тратящий помещает в стек свой полный скрипт погашения (redeem script). Нода проверяет, совпадает ли HASH160 этого скрипта с хешем в выходе. Если не совпадает, выполнение немедленно прерывается с ошибкой. Если совпадает, нода выполняет раскрытый скрипт погашения с оставшимися в стеке данными, чтобы проверить фактические условия траты.
  12. У этой схемы есть острый угол: никто не может проверить скрипт погашения до оплаты, поскольку в блокчейне есть только его хеш. Если ПО получателя сформировало ошибочный скрипт или скрипт утерян, монеты, отправленные на этот адрес, могут навсегда остаться непотраченными.
  13. Когда в августе 2017 года был активирован SegWit, P2SH стал мостом совместимости. Пользователи могли упаковывать новые witness-скрипты в «конверт» P2SH, создавая «вложенные» (nested) адреса, которые по-прежнему начинались с «3». Старые кошельки, не поддерживавшие новые адреса bech32, всё равно могли отправлять средства пользователям SegWit, а получатели с поддержкой SegWit получали скидку на комиссию при трате. Сегодня, хотя ради эффективности предпочтение отдаётся нативному SegWit, P2SH остаётся важным механизмом для сложных контрактов и совместимости со старыми системами.

Ключевые факты

  • Выходы P2PKH хранят 20-байтовый HASH160 публичного ключа, а не сам ключ.
  • Скрипт блокировки `OP_DUP OP_HASH160 <hash> OP_EQUALVERIFY OP_CHECKSIG` имеет ровно 25 байт в длину.
  • Для траты необходимо раскрыть и действительную подпись ECDSA, и публичный ключ, соответствующий сохранённому хешу.
  • Устаревшие (legacy) адреса P2PKH начинаются с '1' и используют кодировку Base58Check с контрольной суммой.
  • P2PKH годами был доминирующим типом выхода для обычных платежей — как до, так и после SegWit.
  • Выполнение сразу же завершается с ошибкой, если операция `OP_EQUALVERIFY` обнаруживает несоответствие между хэшированным ключом и сохраненным хэшем.
  • BIP16 был предложен Гэвином Андресеном и активирован в апреле 2012 года.
  • Выходной скрипт P2SH содержит только HASH160 скрипта погашения и имеет длину 23 байта.
  • BIP17 Люка Дэшджуниора (Luke Dashjr) конкурировал с BIP16 в ходе ожесточённых дебатов с января по март 2012 года.
  • Правила консенсуса ограничивают скрипты погашения 520 байтами — максимальным размером одного элемента, помещаемого в стек.
  • Адреса P2SH используют кодировку Base58Check и всегда начинаются с цифры '3'.
  • Вложенный SegWit (обычно P2SH-P2WPKH) после 2017 года позволял старым кошелькам платить пользователям SegWit.

Упражнение девять, шесть, три, один

9СобратьНайдите в блокчейне Bitcoin 9 реальных входов транзакций, которые тратят средства с адресов P2PKH. Запишите высоту блока, публичный ключ, раскрытый в scriptSig, и соответствующий хеш в выходе.
6СгруппироватьРаспределите эти 9 по 6 группам по периодам: 2009–2011, 2012–2013, 2014–2015, 2016–2017, 2018–2021, с 2022 года и далее. Отметьте сжатые и несжатые ключи.
3Выделить главноеСведите эти группы к 3 отдельным причинам, по которым P2PKH оставался доминирующим, несмотря на появление более эффективных типов выходов после 2017 года.
1КристаллизоватьНапишите одно предложение о том, как `OP_EQUALVERIFY` превращает публичный ключ в обязывающее обязательство ещё до проверки подписи.

Проверка фактов

Даты, цифры и утверждения были проверены по приведенным ниже опубликованным источникам.

Открыть в интерактивной академии →

EN PT ES ZH JA KO DE FR MS