协作头脑风暴
brainstorming
在实现前澄清需求、探索设计选择,并形成清晰的开发方向。
bitcoin-psbt【开发与工程】Partially Signed Bitcoin Transaction format: BIP174 (v0), BIP370 (v2), BIP371 (Taproot fields). Roles (Creator, Updater, Signer, Combiner, Finalizer, Extractor), required fields per input/output type, Taproot-specific fields (tap_key_sig, tap_script_sig, tap_leaf_script, tap_bip32_derivation), magic bytes, separators. USE WHEN: building/signing/coord…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
PSBT = a binary container for a transaction-in-progress, where one party constructs the skeleton, others contribute signatures, and a finalizer emits the broadcastable transaction.
psbt\xff. Tx is fully serialized
in PSBT_GLOBAL_UNSIGNED_TX.| Role | Responsibility |
|---|---|
| Creator | Builds initial PSBT skeleton (inputs, outputs, no sigs). |
| Updater | Adds metadata: non_witness_utxo, witness_utxo, derivation paths, redeem/witness scripts, taptree info. |
| Signer | Reads PSBT, produces partial sigs for inputs it controls. |
| Combiner | Merges multiple Signers' partial PSBTs into one. |
| Finalizer | Replaces partial sigs with final_scriptSig / final_scriptWitness. |
| Extractor | Pulls final tx from finalized PSBT for broadcast. |
Tools: walletprocesspsbt, combinepsbt, finalizepsbt,
decodepsbt, analyzepsbt (Bitcoin Core); hwi signtx (hardware
wallet); Sparrow/Specter/Caravan for coordination.
[5 bytes] magic = b"psbt" + 0xff
[ globals section ]
[ for each input: inputs section, terminated by 0x00 ]
[ for each output: outputs section, terminated by 0x00 ]
Each section is a series of <key, value> pairs:
[varint] key length
[1 byte] key type
[..] key data
[varint] value length
[..] value data
End of section = 0x00 byte (zero-length key).
| Output type | Required |
|---|---|
| Legacy P2PKH/P2SH | non_witness_utxo (full prev tx) |
| SegWit v0 (P2WPKH/P2WSH) | witness_utxo (just the spent output) AND non_witness_utxo recommended (defends against fee-bumping attack on signing devices) |
| P2SH-wrapped SegWit | both, plus redeem_script |
| P2WSH | witness_script |
| Taproot key-path | witness_utxo + taproot_internal_key + tap_bip32_derivation |
| Taproot script-path | above + tap_leaf_script (script + control block) + tap_script_sig |
Always include all spent prevouts for Taproot inputs — sighash commits to all of them (BIP341).
| Section | Type | Name |
|---|---|---|
| Global | 0x00 | PSBT_GLOBAL_UNSIGNED_TX |
| Global | 0x01 | PSBT_GLOBAL_XPUB |
| Global | 0xfb | PSBT_GLOBAL_VERSION (v2 only) |
| Input | 0x00 | PSBT_IN_NON_WITNESS_UTXO |
| Input | 0x01 | PSBT_IN_WITNESS_UTXO |
| Input | 0x02 | PSBT_IN_PARTIAL_SIG |
| Input | 0x03 | PSBT_IN_SIGHASH_TYPE |
| Input | 0x04 | PSBT_IN_REDEEM_SCRIPT |
| Input | 0x05 | PSBT_IN_WITNESS_SCRIPT |
| Input | 0x06 | PSBT_IN_BIP32_DERIVATION |
| Input | 0x07 | PSBT_IN_FINAL_SCRIPTSIG |
| Input | 0x08 | PSBT_IN_FINAL_SCRIPTWITNESS |
| Input | 0x13 | PSBT_IN_TAP_KEY_SIG (BIP371) |
| Input | 0x14 | PSBT_IN_TAP_SCRIPT_SIG |
| Input | 0x15 | PSBT_IN_TAP_LEAF_SCRIPT |
| Input | 0x16 | PSBT_IN_TAP_BIP32_DERIVATION |
| Input | 0x17 | PSBT_IN_TAP_INTERNAL_KEY |
| Input | 0x18 | PSBT_IN_TAP_MERKLE_ROOT |
| Output | 0x00 | PSBT_OUT_REDEEM_SCRIPT |
| Output | 0x01 | PSBT_OUT_WITNESS_SCRIPT |
| Output | 0x02 | PSBT_OUT_BIP32_DERIVATION |
| Output | 0x05 | PSBT_OUT_TAP_INTERNAL_KEY |
| Output | 0x06 | PSBT_OUT_TAP_TREE |
| Output | 0x07 | PSBT_OUT_TAP_BIP32_DERIVATION |
Proprietary fields use type 0xfc with key prefix.
PSBT can be encoded as:
A "PSBT object" with the right magic bytes round-trips losslessly.
non_witness_utxo for SegWit inputs on hardware signers
→ device refuses to sign (post Coinkite/Trezor/Ledger fix for
fee-bumping attack).bip32_derivation paths → device cannot find the key.tap_internal_key for Taproot inputs → finalizer cannot
reconstruct script-path / verify key-path.