40 / 736SCRIPT

Bitcoin Script

Як Bitcoin перевіряє право витрачати кошти

Bitcoin Script записує умови, за яких можна витратити конкретну суму біткоїнів. Зазвичай потрібен чинний цифровий підпис, іноді кілька підписів або виконання часової умови. Гаманець надає потрібні дані, а вузли мережі самостійно їх перевіряють.

Bitcoin Script — це мова умов витрачання. Кожен вихід транзакції, тобто сума з умовами її наступного використання, містить ці умови. Той, хто хоче його витратити, має їх виконати. Script допомагає відповісти на просте запитання: чи може саме ця транзакція використати саме ці кошти?

Аліса отримує 20 000 sat — двадцять тисяч найменших одиниць біткоїна. Мережа не відкриває рахунок на її ім’я. Вона створює вихід транзакції: суму й умову її подальшого витрачання. Поки вихід не витрачено, його називають UTXO. Для звичайного платежу умова вимагає підпису відповідним ключем. Коли Аліса згодом платить, її гаманець вибирає цей вихід, посилається на нього новим входом транзакції та створює цифровий підпис. Для цього він використовує приватний ключ, нікуди його не надсилаючи; інші перевіряють підпис публічним ключем. Знати адресу Аліси для отримання платежів недостатньо. Умови початкового виходу записано в полі scriptPubKey, а Bitcoin Script визначає, як перевіряти їх виконання. Вузол — не службовець, який упізнає Алісу, а комп’ютер, що перевіряє правила. Крім підпису, він має, наприклад, перевірити, чи цей вихід уже не витрачено. Транзакція чинна лише тоді, коли виконано всі застосовні правила. [4] [2]

Для звичайних платежів умови формує гаманець. Робіть резервну копію за його інструкцією: звичайне відновлення за словами в сумісному гаманці не означає, що треба вручну зберігати кожен скрипт. У складнішій конфігурації, наприклад Multisig із кількома потрібними підписами, слова одного учасника можуть не описувати всього порядку витрачання. Для повсякденного використання краще обрати гаманець із перевіреними процедурами, ніж вручну складати скрипти в шістнадцятковому записі. Дескриптори виходів описують тип скрипту, ключі та їх виведення; так вони допомагають визначити, що має шукати відновлений гаманець. Самого приватного ключа може бути недостатньо для відновлення складнішої конфігурації. Зберігайте також потрібні скрипти й дані про походження ключів, тобто звідки та як вони були виведені, і перевіряйте заплановані шляхи витрачання. [11]

Наступні розділи показують, як умови записуються всередині транзакції; для повсякденних платежів знати це не потрібно. Поле scriptSig і частина під назвою witness передають дані для перевірки. Хеш — це відбиток даних, а часове блокування забороняє витрачання до певної межі. Стек можна уявити як стос елементів, з якими працюють згори. Script обробляє дані за допомогою стека: додає до нього значення, а інструкції, які називають кодами операцій, знімають їх, порівнюють або обробляють інакше. Інструкції підпису перевіряють підписи; приватні ключі та створення підписів до цієї перевірки не належать. Мова дає змогу поєднувати підписи, умови на основі хешів і часові блокування. Вона не має циклів загального призначення й не є повною за Тюрінгом: у ній не можна описати всі обчислення, доступні в універсальній мові програмування. Вузол повинен застосовувати точні правила для відповідного типу виходу та версії скрипту. [1] [3]

Вихід P2PKH (Pay to Public Key Hash) зазвичай має вигляд OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG. Вхід надає підпис і публічний ключ у своєму scriptSig. Перевірка встановлює, чи відповідає хеш публічного ключа значенню у виході, а потім перевіряє підпис. Тому знати лише адресу чи публічний ключ для такого витрачання недостатньо. Приватний ключ використовує гаманець, який підписує, а не вузол, що перевіряє транзакцію. [1]

P2SH згідно з BIP16 зберігає у виході хеш скрипту. Вхід, який витрачає цей вихід, надає відповідний redeemScript, тобто скрипт, розкритий під час витрачання, разом із потрібними даними. Його scriptSig може містити лише інструкції, що додають дані до стека. Вузол спочатку перевіряє збіг хешу, а потім виконує redeemScript з рештою елементів стека. Самого правильного хешу для витрачання недостатньо: потрібно також виконати умови цього скрипту. [5]

У SegWit версії 0 дані для перевірки перенесено до частини транзакції під назвою witness. Це список елементів даних, а не сам по собі скрипт. P2WPKH використовує підпис і публічний ключ; P2WSH містить також witnessScript, хеш SHA256 якого має відповідати виходу. У нативному SegWit scriptSig порожній. Якщо використовується обгортка P2SH, він містить лише інструкцію додавання відповідної програми witness до стека; самі дані для перевірки залишаються у witness. [6]

Перевірка підпису використовує повідомлення, отримане з транзакції за визначеною процедурою. Режим SIGHASH визначає, які її частини підпис захищає від змін. Тому не можна автоматично вважати, що кожен підпис охоплює всю транзакцію. BIP143 для операцій підпису в SegWit версії 0 завжди включає також суму виходу, що витрачається. Гаманець має знати правильні дані та вибраний режим; Script під час перевірки не оцінює людський намір підписувача. [7]

Taproot згідно з BIP341 дає змогу витратити вихід P2TR (Pay to Taproot) двома способами. Шлях через ключ перевіряє підпис Шнорра за публічним ключем виходу, не розкриваючи скрипту. Шлях через скрипт натомість розкриває вибраний скрипт і контрольний блок, який називають control block і який доводить його зв’язок із виходом. Решту скриптів у дереві розкривати не потрібно. Правила для розкритого скрипту залежать також від версії відповідного листка. [8]

BIP342 визначає Tapscript для листків Taproot версії 0xc0. Інструкції підпису тут використовують підписи Шнорра, а OP_CHECKSIGADD дає змогу побудувати умову, що вимагає кількох підписів. Стара операція OP_CHECKMULTISIG заборонена під час виконання. Попередній ліміт довжини скрипту 10 000 байтів і ліміт у 201 код операції за старими правилами підрахунку не застосовуються. Кількість операцій підпису обмежує бюджет, визначений розміром witness; обмеження стека зберігаються. Тому ліміти однієї версії не можна подавати як загальні властивості всієї мови Script. [9]

Правила консенсусу визначають чинність витрачання в блоці. Стандартність означає додаткові місцеві правила вузла для приймання непідтверджених транзакцій до Mempool та їх поширення; це не процес стандартизації. Тому чинна за консенсусом транзакція не обов’язково поширюватиметься звичайним чином. Особливої уваги потребує OP_SUCCESSx у Tapscript: після успішного проходження попередніх перевірок його розпізнавання під час декодування завершує перевірку скрипту успіхом ще до звичайного виконання та перевірок стека. Це можливість для майбутніх розширень, а не звичайна безпечна умова витрачання. [10] [9]

Для повної картини прочитайте також Транзакція, Multisig, Timelock, Taproot. На цю статтю також посилаються Hash, SHA-256, Правила консенсусу, Timelock.

DOC · 001Bitcoin Developer Guide — ScriptsДокументація DOC · 002Bitcoin whitepaperПервинне джерело DOC · 003Bitcoin Core — script interpreterПервинне джерело DOC · 004Bitcoin Developer Guide — TransactionsДокументація DOC · 005BIP 16 — Pay to Script HashПервинне джерело DOC · 006BIP 141 — Segregated WitnessПервинне джерело DOC · 007BIP 143 — Transaction Signature Verification for Version 0 Witness ProgramПервинне джерело DOC · 008BIP 341 — TaprootПервинне джерело DOC · 009BIP 342 — Validation of Taproot ScriptsПервинне джерело DOC · 010Bitcoin Core — Transaction Relay PolicyПервинне джерело DOC · 011BIP 380 — Output Script Descriptors General OperationПервинне джерело
Переглянуто: Спочатку джерела · Не інвестиційна порада