PSBT v2 — друга визначена специфікацією версія формату Partially Signed Bitcoin Transaction, тобто частково підписаної транзакції Bitcoin. BIP 370 описує цей спільний робочий формат для гаманців і пристроїв підписання. Він може містити пропозицію ще без жодного підпису. Формат допомагає кільком учасникам складати транзакцію, але не замінює їхніх перевірок чи правил мережі Bitcoin.
Анна та Ян хочуть разом оплатити один рахунок. Кожен додає частину власних коштів і ставить підпис на своєму пристрої. Їм потрібно обмінятися узгодженим проєктом, а не приватними ключами. Приватний ключ — це секретне число, за допомогою якого гаманець створює цифровий підпис для дозволу на витрачання коштів. Для передавання проєкту PSBT слугує робочим конвертом із транзакцією та супровідними даними. Входи вказують на попередні суми, що витрачаються; виходи визначають нові суми та умови їх подальшого витрачання. Початковий PSBT v0 зберігає цю структуру у фіксованій глобальній непідписаній транзакції. У v2 входи й виходи можна додавати поступово за відповідними правилами. Перевага полягає у спільному складанні, а не в можливості довільно переписувати вже підписане. [1] [2]
Анні не потрібно читати кожне технічне поле. Проте на довіреному пристрої підписання вона має перевірити справжнього одержувача, суму, комісію та можливу решту, що повертається до її гаманця. Останню деталь легко пропустити: чужий вихід не можна прийняти за власну решту. Пристрій повинен перевірити дані UTXO, тобто ще не витрачених виходів, і відповідність їхніх умов тому, що підписується. Шлях виведення ключа описує кроки, за якими гаманець отримує конкретний ключ зі свого головного ключа. Саме зазначення цього шляху не доводить належність коштів. Пристрій підписання також має правильно тлумачити SIGHASH — налаштування, яке визначає, які частини транзакції захищає підпис. Для підписання не потрібно додавати до передаваного файлу приватний ключ чи Seed Phrase — слова резервної копії гаманця. [2] [4]
Напис про підтримку PSBT у застосунку чи на пристрої ще не означає підтримки v2. Перевіряти слід увесь шлях: створення, імпорт, підписання та повернення результату між конкретними програмами й пристроями. PSBT v0 та v2 не є безпосередньо взаємозамінними. Перетворення на v0 потребує складання непідписаної транзакції та приведення полів до правил цієї версії; заміни числа недостатньо. Taproot, новіший спосіб визначення умов витрачання виходів Bitcoin, також не тотожний v2. BIP 371 описує відповідні дані для підписання в обох версіях PSBT. Невелика перевірка всього процесу підтверджує сумісність конкретного набору засобів, а не правильність усіх майбутніх платежів. [1] [3]
Версія формату файлу та версія транзакції Bitcoin означають різні речі. У v2 поле PSBT_GLOBAL_VERSION має містити 2, а старе поле PSBT_GLOBAL_UNSIGNED_TX має бути відсутнє. Окреме обов’язкове поле PSBT_GLOBAL_TX_VERSION визначає версію самої транзакції. Кількості входів і виходів також обов’язкові. Завдяки такому поділу дані розташовані біля відповідних елементів, а програмі не потрібно додатково шукати їх у спільній структурі. Якщо творець передає подальше складання іншим учасникам, BIP 370 вимагає належних прапорців змін і версії транзакції щонайменше 2. Це робочий формат, а не нові правила консенсусу мережі. [1]
Кожному входу потрібні TXID — ідентифікатор попередньої транзакції — та індекс конкретного виходу, який із неї витрачається. Самого TXID недостатньо: транзакція може мати кілька виходів. Кожен новий вихід містить суму в satoshi, найменших одиницях Bitcoin, та scriptPubKey — скрипт з умовами витрачання. Додавання елемента повинно також змінити відповідну глобальну кількість. Необов’язкове поле sequence містить додаткове керувальне значення входу; якщо воно відсутнє, використовується 0xffffffff. Ці дані описують складання транзакції. Вони не замінюють відомостей про суми й умови витрачання UTXO, потрібних пристрою для безпечної оцінки підпису та комісії. [1]
Припустімо, Яну потрібно додати ще один вхід. Програма не може вважати це дозволеним лише тому, що має файл. У PSBT_GLOBAL_TX_MODIFIABLE біт 0 указує на можливість змін входів, а біт 1 — виходів. Біт 2 повідомляє про підпис SIGHASH_SINGLE, який пов’язує вхід із виходом на відповідній позиції. Цю пару необхідно зберегти й під час вставляння додаткових елементів. Тому той, хто складає транзакцію, аналізує наявні підписи та їхні обмеження. Прапорці передають інформацію програмам, що співпрацюють; вони не обходять криптографічного підпису й не роблять неприпустиму зміну допустимою. [1]
Деякі входи вимагають дочекатися певної висоти блоку або часової межі, перш ніж транзакцію можна буде використати. Блок — це група транзакцій, записана до спільної історії мережі; його висота вказує на місце в ланцюжку. Спільне поле nLockTime має відповідати типу вимог, сумісному з усіма входами. Обирається найбільше потрібне значення цього типу; якщо можливі обидва типи, перевага надається висоті блоку. Отже, висоту й час не можна просто порівняти як два звичайні числа. Якщо жоден вхід не містить вимоги, застосовується глобальне запасне значення, а за його відсутності — 0. Вхід із несумісною вимогою додавати не можна. Якщо підписи вже є, новий вхід також не повинен змінювати обчислений nLockTime. Самі ці поля не гарантують виконання всіх правил часових блокувань. [1]
Кожен підпис обмежує подальші зміни. BIP 370 вимагає вимкнути зміни входів без SIGHASH_ANYONECANPAY і зміни виходів без SIGHASH_NONE; за SIGHASH_SINGLE потрібно позначити пару, яку слід зберегти. Ці назви визначають різні межі захисту підписом, а не перемикачі для випадкових експериментів новачка. Коли всі входи готові, фіналізація формує необхідні дані підписів, а екстрактор складає з полів транзакцію в мережевому форматі. Лише її надсилання дає вузлам змогу оцінити транзакцію, а майнеру — включити її до блоку. Тому Анна та Ян розрізняють проєкт, підписаний результат і підтверджений платіж: саме передавання PSBT не є ані підписанням, ані підтвердженням. [1] [2] [4]
Для повної картини прочитайте також PSBT, Hardware Wallet, Multisig, Taproot, Bitcoin, UTXO.