Bitcoin(PSBT)
Bitcoin 请求就是 PSBT。由你的钱包构建 PSBT;BitTool Signer 添加签名后返回 PSBT;再由你的钱包执行 finalize 并广播。
传输方式
| 请求 | 响应 | 说明 |
|---|---|---|
ur:crypto-psbt | ur:crypto-psbt | 推荐。UR 正文为承载 PSBT 的 CBOR 字节串。 |
ur:psbt | ur:psbt | 注册表中较新的名称,内容相同。 |
BBQr(B$…,编码 H、2、Z) | BBQr(2 或 H) | Coinkite 的格式。接受 Z(deflate);响应使用 2(Base32),如果请求使用 H,则响应也使用 H。 |
单个二维码中的 Base64(cHNidP…)或十六进制(70736274ff…)文本 | 不超过 1,800 个字符时返回相同形式的文本,否则返回动态 ur:crypto-psbt | 适用于体积较小的交易。 |
.psbt 文件(Base64 或十六进制,可以换行) | 相同 | 通过签名手机上的“文件”App 或隔空投送(AirDrop)传递。 |
响应始终使用请求自身的格式(上表注明的情况除外),因此你可以复用已有的解码器。
PSBT 必须包含的内容
| 要求 | 详情 |
|---|---|
| 版本 | PSBT v0 或 v2(BIP 370)。v0 是最稳妥的选择。 |
| 大小 | 1–100 个输入,1–100 个输出。 |
| 派生信息 | 签名器需要签名的每个输入,都必须为其密钥携带 bip32Derivation(主指纹 + 完整路径)。Taproot 输入使用 tapBip32Derivation 和 tapInternalKey。 |
| 前序交易 | Legacy 和 SegWit v0 输入(P2PKH、P2WPKH、P2SH-P2WPKH、P2WSH …)需要在 nonWitnessUtxo 中提供完整的前序交易。只有当所有输入都是 Taproot 时,才接受仅提供 witnessUtxo。 |
| Sighash | SIGHASH_ALL,Taproot 也可使用 SIGHASH_DEFAULT。其他类型一律拒绝。 |
| 找零 | 找零输出也要带上 bip32Derivation。只有在 BitTool Signer 用自己的密钥重新推导出某个输出的脚本之后,才会将其标记为“找零”。 |
| 输出 | 标准脚本,以及不超过 83 字节的 OP_RETURN。 |
| 网络 | 仅限主网。 |
nonWitnessUtxoSegWit v0 签名承诺了所花费输入的金额,但没有承诺其他输入的金额。恶意的协调方可以在两轮签名中谎报输入金额,诱使签名器支付巨额手续费(即 2020 年披露的 SegWit 手续费攻击)。有了完整的前序交易,签名器就能自行核对每一个金额。Taproot 签名会承诺所有输入的金额,因此全部由 Taproot 输入构成的交易可以豁免。
支持的脚本
| 脚本 | 是否签名 |
|---|---|
| P2PKH、P2WPKH、P2SH-P2WPKH | 是(单密钥) |
| P2TR 密钥路径(BIP86) | 是 |
多签 P2SH、P2WSH、P2SH-P2WSH(multi/sortedmulti) | 是,每个本地密钥一个部分签名 |
P2TR 脚本路径,CHECKSIG/CHECKSIGVERIFY 和 CHECKSIGADD 门限叶子(叶子版本 0xc0) | 是 |
| MuSig2 及其他脚本 | 否 |
响应
响应就是你的 PSBT 加上签名:ECDSA 输入使用 partialSig,Taproot 输入使用 tapKeySig 或 tapScriptSig。签名器不会执行 finalize,其他内容也都保持不变。在 finalize 之前:
- 检查未签名交易与你发送的逐字节一致(PSBT 传输方式中没有请求 ID)。
- 针对对应的输入验证每个新增签名。
- 如果是多签,与其他共同签名方的 PSBT 合并。
- 执行 finalize、提取交易并广播。
- 带找零的销毁(R3-01,低,仅 iPhone)。对于包含金额非零的
OP_RETURN输出、同时又有找零的销毁交易,BitTool Signer 结果页面和活动记录中的一行摘要显示为“Every output returns to your wallet”(所有输出都回到你的钱包)。签名界面本身会正确显示销毁、其金额以及高风险,PSBT 也不受影响。BitTool Signer Android 1.0.0 会在摘要中同样显示销毁。 - 任意索引的找零(BTS-08,中,两款 App)。只要输出的脚本与钱包自身任一单签配置在任意索引上相符,就会被视为找零,包括观察钱包永远不会扫描到的索引。请把找零放在常规索引上;如果某个请求把全部资金转到用户钱包中一个不寻常的路径,请保持警惕。
参见安全评审。
代码
使用 bitcoinjs-lib 构建 PSBT,并用 Keystone 的 @keystonehq/bc-ur-registry 将其封装为 ur:crypto-psbt:
import * as bitcoin from 'bitcoinjs-lib';
import { CryptoPSBT } from '@keystonehq/bc-ur-registry';
import { URDecoder } from '@ngraveio/bc-ur';
import { secp256k1 } from '@noble/curves/secp256k1.js';
// utxos: [{ txid, vout, value, prevTxHex, pubkey, path }] path like "m/84'/0'/0'/0/3"
export function buildPsbt({ utxos, to, amount, change, masterFingerprint }) {
const fingerprint = Buffer.from(masterFingerprint, 'hex');
const psbt = new bitcoin.Psbt(); // mainnet
for (const u of utxos) {
const prevTx = bitcoin.Transaction.fromHex(u.prevTxHex);
psbt.addInput({
hash: u.txid,
index: u.vout,
nonWitnessUtxo: Buffer.from(u.prevTxHex, 'hex'), // required for SegWit v0 and legacy inputs
witnessUtxo: { script: prevTx.outs[u.vout].script, value: u.value },
bip32Derivation: [{ masterFingerprint: fingerprint, path: u.path, pubkey: u.pubkey }],
});
}
psbt.addOutput({ address: to, value: amount });
psbt.addOutput({ // change: give the path so the signer can recognize it
address: change.address, value: change.value,
bip32Derivation: [{ masterFingerprint: fingerprint, path: change.path, pubkey: change.pubkey }],
});
const encoder = new CryptoPSBT(psbt.toBuffer()).toUREncoder(400);
const frames = [];
for (let i = 0; i < encoder.fragmentsLength; i++) frames.push(encoder.nextPart().toUpperCase());
return { psbt, frames };
}
读回已签名的 PSBT,检查后执行 finalize:
const validator = (pubkey, msghash, signature) => secp256k1.verify(signature, msghash, pubkey, { prehash: false });
export function finalizeSignedPsbt(frames, original) {
const decoder = new URDecoder();
for (const frame of frames) decoder.receivePart(frame);
if (!decoder.isSuccess()) throw new Error('Incomplete or invalid QR');
const ur = decoder.resultUR();
if (ur.type !== 'crypto-psbt') throw new Error(`Expected crypto-psbt, got ${ur.type}`);
const signed = bitcoin.Psbt.fromBuffer(CryptoPSBT.fromCBOR(ur.cbor).getPSBT());
// The signer only adds signatures: the transaction itself must be unchanged.
if (!signed.data.globalMap.unsignedTx.toBuffer().equals(original.data.globalMap.unsignedTx.toBuffer()))
throw new Error('The signed PSBT is for a different transaction');
if (!signed.validateSignaturesOfAllInputs(validator)) throw new Error('Invalid signature');
signed.finalizeAllInputs();
return signed.extractTransaction().toHex(); // ready to broadcast
}
测试向量
- P2WPKH(含找零)
- Taproot 密钥路径
输入 100,000 sats,位于 m/84'/0'/0'/0/0;向 bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4 发送 60,000 sats,39,000 sats 找零到 m/84'/0'/0'/1/0,手续费 1,000 sats。前序交易为合成数据。
请求(你的钱包 → BitTool Signer)
cHNidP8BAHECAAAAAekP8Koj3Yg9KuehyjwZqkAWg+Oc9XIc9Mif9dK3rUrGAAAAAAD/////AmDqAAAAAAAAFgAUdR526BmRltRUlBxF0bOjI/FDO9ZYmAAAAAAAABYAFD40mF3Kb93J+zaZQOTH2OKHP1KcAAAAAAABAFICAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAD/////AaCGAQAAAAAAFgAUwM681sPTyox13F7GLr5VMw75EOIAAAAAAQEfoIYBAAAAAAAWABTAzrzWw9PKjHXcXsYuvlUzDvkQ4iIGAzDVT9DdQgpuX402JPXzSCyuNQ951fB1O/W+75wtka88GHPF2gpUAACAAAAAgAAAAIAAAAAAAAAAAAAAIgIDAlMkiI5Cmrjj268feAJki5zQHptBhIXF+kwbm1cA4aYYc8XaClQAAIAAAACAAAAAgAEAAAAAAAAAAA==
显示二维码文本和原始 CBOR
UR:CRYPTO-PSBT/1-3/LPADAXCFADJLCYRFDSIHPRHDKGHKADJZJOJKIDJYZMADAEJSAOAEAEAEADWLBSWTPKCNUTLOFSDRVDOYSGFNCFPKFZCMLSVLNSYKJPCEWKSPNEYKTDRLPMGESWAEAEAEAEAEZMZMZMZMAOHNWDAEAEAEAEAEAECMAEBBKPCKKOVSCFMEMTTYGHMWCEFETTQDOTCNWNFXFRTBHDMKAEAEAEAEAEAECMAEBBFMEEMKHLSGJLUTSOZOENNLFZVESTTPVOLTFHGMNSAEAEAEQZMKTNSA
UR:CRYPTO-PSBT/2-3/LPAOAXCFADJLCYRFDSIHPRHDKGAEAEADAEGMAOAEAEAEADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADAEAEAEAEAEZMZMZMZMADNBLNADAEAEAEAEAECMAEBBRTTORFTBSRTESGLKKPUOHYSWDMRNGOEOBAYTBEVOAEAEAEAEADADCTNBLNADAEAEAEAEAECMAEBBRTTORFTBSRTESGLKKPUOHYSWDMRNGOEOBAYTBEVOCPAMGWBSRYCW
UR:CRYPTO-PSBT/3-3/LPAXAXCFADJLCYRFDSIHPRHDKGAXDYTLGWTIUTFWBKJTHELGENDKYKWFFDDWPLECBSKKTLWTKPFRYKRNWSNSDPMEPEFNCSJKSKTNBKGHAEAELAAEAEAELAAEAEAELAAEAEAEAEAEAEAEAEAEAECPAOAXAOGUDKLOMNFWNYROVLUYPECTKSAOIELUNSTICKNDFPLRLPSKZSGSCWNDHGAEVYOLCSJKSKTNBKGHAEAELAAEAEAELAAEAEAELAADAEAEAEAEAEAEAEAEAEAEGWCEHDPR
59016c70736274ff0100710200000001e90ff0aa23dd883d2ae7a1ca3c19aa401683e39cf5721cf4c89ff5d2b7ad4ac60000000000ffffffff0260ea000000000000160014751e76e8199196d454941c45d1b3a323f1433bd658980000000000001600143e34985dca6fddc9fb369940e4c7d8e2873f529c0000000000010052020000000101010101010101010101010101010101010101010101010101010101010101010000000000ffffffff01a086010000000000160014c0cebcd6c3d3ca8c75dc5ec62ebe55330ef910e20000000001011fa086010000000000160014c0cebcd6c3d3ca8c75dc5ec62ebe55330ef910e222060330d54fd0dd420a6e5f8d3624f5f3482cae350f79d5f0753bf5beef9c2d91af3c1873c5da0a54000080000000800000008000000000000000000000220203025324888e429ab8e3dbaf1f7802648b9cd01e9b418485c5fa4c1b9b5700e1a61873c5da0a540000800000008000000080010000000000000000
响应(BitTool Signer → 你的钱包)
cHNidP8BAHECAAAAAekP8Koj3Yg9KuehyjwZqkAWg+Oc9XIc9Mif9dK3rUrGAAAAAAD/////AmDqAAAAAAAAFgAUdR526BmRltRUlBxF0bOjI/FDO9ZYmAAAAAAAABYAFD40mF3Kb93J+zaZQOTH2OKHP1KcAAAAAAABAFICAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAD/////AaCGAQAAAAAAFgAUwM681sPTyox13F7GLr5VMw75EOIAAAAAAQEfoIYBAAAAAAAWABTAzrzWw9PKjHXcXsYuvlUzDvkQ4iICAzDVT9DdQgpuX402JPXzSCyuNQ951fB1O/W+75wtka88SDBFAiEAnxTBvsytWOKIqCL+jVnOZoU8wKKB3sg9FqBU6YKagoUCIC4lC/U2vuJKimL4vEacD8f6CnzzwQjDbBZOBoNWSJMgASIGAzDVT9DdQgpuX402JPXzSCyuNQ951fB1O/W+75wtka88GHPF2gpUAACAAAAAgAAAAIAAAAAAAAAAAAAAIgIDAlMkiI5Cmrjj268feAJki5zQHptBhIXF+kwbm1cA4aYYc8XaClQAAIAAAACAAAAAgAEAAAAAAAAAAA==
显示二维码文本和原始 CBOR
UR:CRYPTO-PSBT/1-3/LPADAXCFADUYCYVWCKDTWYHDNEHKADTPJOJKIDJYZMADAEJSAOAEAEAEADWLBSWTPKCNUTLOFSDRVDOYSGFNCFPKFZCMLSVLNSYKJPCEWKSPNEYKTDRLPMGESWAEAEAEAEAEZMZMZMZMAOHNWDAEAEAEAEAEAECMAEBBKPCKKOVSCFMEMTTYGHMWCEFETTQDOTCNWNFXFRTBHDMKAEAEAEAEAEAECMAEBBFMEEMKHLSGJLUTSOZOENNLFZVESTTPVOLTFHGMNSAEAEAEAEAEADAEGMAOAEAEAEADADADADADADADADADADADADADADADADADADADADADADADADADADADCLBBLDOY
UR:CRYPTO-PSBT/2-3/LPAOAXCFADUYCYVWCKDTWYHDNEADADADADADADAEAEAEAEAEZMZMZMZMADNBLNADAEAEAEAEAECMAEBBRTTORFTBSRTESGLKKPUOHYSWDMRNGOEOBAYTBEVOAEAEAEAEADADCTNBLNADAEAEAEAEAECMAEBBRTTORFTBSRTESGLKKPUOHYSWDMRNGOEOBAYTBEVOCPAOAXDYTLGWTIUTFWBKJTHELGENDKYKWFFDDWPLECBSKKTLWTKPFRYKRNWSNSDPMEPEFNFDDYFEAOCLAENEBBSERNSFPMHDVOLOPDCPZELGHKTOIYLPFNRTOELYUESPFSCMNBGHWLLFNYLFLPAONLJTAAPK
UR:CRYPTO-PSBT/3-3/LPAXAXCFADUYCYVWCKDTWYHDNECXDMDABDYKENRNVOGELEIDYARFFGNSBSSTZSBKKEWFSEAYSRJZCMGLAMLSHFFDMUCXADCPAMAXDYTLGWTIUTFWBKJTHELGENDKYKWFFDDWPLECBSKKTLWTKPFRYKRNWSNSDPMEPEFNCSJKSKTNBKGHAEAELAAEAEAELAAEAEAELAAEAEAEAEAEAEAEAEAEAECPAOAXAOGUDKLOMNFWNYROVLUYPECTKSAOIELUNSTICKNDFPLRLPSKZSGSCWNDHGAEVYOLCSJKSKTNBKGHAEAELAAEAEAELAAEAEAELAADAEAEAEAEAEAEAEAEAEAEHHDLWYGS
5901d870736274ff0100710200000001e90ff0aa23dd883d2ae7a1ca3c19aa401683e39cf5721cf4c89ff5d2b7ad4ac60000000000ffffffff0260ea000000000000160014751e76e8199196d454941c45d1b3a323f1433bd658980000000000001600143e34985dca6fddc9fb369940e4c7d8e2873f529c0000000000010052020000000101010101010101010101010101010101010101010101010101010101010101010000000000ffffffff01a086010000000000160014c0cebcd6c3d3ca8c75dc5ec62ebe55330ef910e20000000001011fa086010000000000160014c0cebcd6c3d3ca8c75dc5ec62ebe55330ef910e222020330d54fd0dd420a6e5f8d3624f5f3482cae350f79d5f0753bf5beef9c2d91af3c4830450221009f14c1beccad58e288a822fe8d59ce66853cc0a281dec83d16a054e9829a828502202e250bf536bee24a8a62f8bc469c0fc7fa0a7cf3c108c36c164e0683564893200122060330d54fd0dd420a6e5f8d3624f5f3482cae350f79d5f0753bf5beef9c2d91af3c1873c5da0a54000080000000800000008000000000000000000000220203025324888e429ab8e3dbaf1f7802648b9cd01e9b418485c5fa4c1b9b5700e1a61873c5da0a540000800000008000000080010000000000000000
由你的钱包组装
02000000000101e90ff0aa23dd883d2ae7a1ca3c19aa401683e39cf5721cf4c89ff5d2b7ad4ac60000000000ffffffff0260ea000000000000160014751e76e8199196d454941c45d1b3a323f1433bd658980000000000001600143e34985dca6fddc9fb369940e4c7d8e2873f529c024830450221009f14c1beccad58e288a822fe8d59ce66853cc0a281dec83d16a054e9829a828502202e250bf536bee24a8a62f8bc469c0fc7fa0a7cf3c108c36c164e06835648932001210330d54fd0dd420a6e5f8d3624f5f3482cae350f79d5f0753bf5beef9c2d91af3c00000000
6f492df497b5e455fb3305d0272fe9c6dc3d8cc9d0054be3aaefee77daca82b7
输入 50,000 sats,位于 m/86'/0'/0'/0/0,仅提供 witnessUtxo(因为所有输入都是 Taproot,所以允许);发送 49,000 sats,手续费 1,000 sats。Schnorr 签名使用新生成的辅助随机数,因此你自己对该 PSBT 生成的签名会有所不同;请验证签名,而不是比较字节。
请求(你的钱包 → BitTool Signer)
cHNidP8BAFICAAAAAX/dUwHqQRbJZhU8W3fRniz4rOZuphwyI6FEAba4ela5AAAAAAD/////AWi/AAAAAAAAFgAUdR526BmRltRUlBxF0bOjI/FDO9YAAAAAAAEBK1DDAAAAAAAAIlEgpghp8NvPHcZZyc7Lr4BQE16p6M3EhwU/HcaICUncaEwhFsyKS8ZNiXvdxfvC9nD3qLoLOGd5EGzxIjxvxdfNb8EVGQBzxdoKVgAAgAAAAIAAAACAAAAAAAAAAAABFyDMikvGTYl73cX7wvZw96i6CzhneRBs8SI8b8XXzW/BFQAA
显示二维码文本和原始 CBOR
UR:CRYPTO-PSBT/1-2/LPADAOCSWPCYWMRDFWONHDKOHDWDJOJKIDJYZMADAEGMAOAEAEAEADLBUTGUADWDFPCMSOIYBZFNHPKTTTNNDWYAPSVAJTOLCEEYCNOYFYADRPROKNHFRHAEAEAEAEAEZMZMZMZMADISRSAEAEAEAEAEAECMAEBBKPCKKOVSCFMEMTTYGHMWCEFETTQDOTCNWNFXFRTBAEAEAEAEAEADADDNGDSRAEAEAEAEAEAECPGYCXOLAYINWTUYTKCASWHKSOTOAEGWMWTI
UR:CRYPTO-PSBT/2-2/LPAOAOCSWPCYWMRDFWONHDKOSBPELAGDBWHYPTVSSNSSLTAHFHCASWLOASGAUOISGSCLCMSFLEGRSWGTLDKGUTSKZOSAYNJOYLPDRDBDETIOKKBEJZWNCPFNJLSKTSSNJLSEBZCFAEJKSKTNBKHFAEAELAAEAEAELAAEAEAELAAEAEAEAEAEAEAEAEADCHCXSFLEGRSWGTLDKGUTSKZOSAYNJOYLPDRDBDETIOKKBEJZWNCPFNJLSKTSSNJLSEBZAEAEEOJZGYLO
58ea70736274ff01005202000000017fdd5301ea4116c966153c5b77d19e2cf8ace66ea61c3223a14401b6b87a56b90000000000ffffffff0168bf000000000000160014751e76e8199196d454941c45d1b3a323f1433bd6000000000001012b50c3000000000000225120a60869f0dbcf1dc659c9cecbaf8050135ea9e8cdc487053f1dc6880949dc684c2116cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115190073c5da0a5600008000000080000000800000000000000000011720cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc1150000
响应(BitTool Signer → 你的钱包)
cHNidP8BAFICAAAAAX/dUwHqQRbJZhU8W3fRniz4rOZuphwyI6FEAba4ela5AAAAAAD/////AWi/AAAAAAAAFgAUdR526BmRltRUlBxF0bOjI/FDO9YAAAAAAAEBK1DDAAAAAAAAIlEgpghp8NvPHcZZyc7Lr4BQE16p6M3EhwU/HcaICUncaEwBE0CiqtbEW/l3qZ5NrQB8IaRcXT9o+CcVa49IBDXZJwmDFlYRnfkafMOiF5IiWbEjfOaLjurboMktvSVjXD4g2UFPIRbMikvGTYl73cX7wvZw96i6CzhneRBs8SI8b8XXzW/BFRkAc8XaClYAAIAAAACAAAAAgAAAAAAAAAAAARcgzIpLxk2Je93F+8L2cPeougs4Z3kQbPEiPG/F181vwRUAAA==
显示二维码文本和原始 CBOR
UR:CRYPTO-PSBT/1-2/LPADAOCFADDYCYHSFRYNOTHDMKHKADDPJOJKIDJYZMADAEGMAOAEAEAEADLBUTGUADWDFPCMSOIYBZFNHPKTTTNNDWYAPSVAJTOLCEEYCNOYFYADRPROKNHFRHAEAEAEAEAEZMZMZMZMADISRSAEAEAEAEAEAECMAEBBKPCKKOVSCFMEMTTYGHMWCEFETTQDOTCNWNFXFRTBAEAEAEAEAEADADDNGDSRAEAEAEAEAEAECPGYCXOLAYINWTUYTKCASWHKSOTOSBPELAGDBWHYPTVSSNSSLTAHFHCASWLOASGAUOISGSADBWFZOEPKTBSSHPYTKTPTNNGMJTUYAH
UR:CRYPTO-PSBT/2-2/LPAOAOCFADDYCYHSFRYNOTHDMKGTPMAEKECLOXHHHLFHISYADIBZJEMYFDAAECTADIASLSCMHFBYNTYTCYKESROECHMOCPHKPACNKEVALUMNWDUYNBSODPRYDAIAHHFMCXTAFPGWCLCMSFLEGRSWGTLDKGUTSKZOSAYNJOYLPDRDBDETIOKKBEJZWNCPFNJLSKTSSNJLSEBZCFAEJKSKTNBKHFAEAELAAEAEAELAAEAEAELAAEAEAEAEAEAEAEAEADCHCXSFLEGRSWGTLDKGUTSKZOSAYNJOYLPDRDBDETIOKKBEJZWNCPFNJLSKTSSNJLSEBZAEAEFPRTCNGO
59012d70736274ff01005202000000017fdd5301ea4116c966153c5b77d19e2cf8ace66ea61c3223a14401b6b87a56b90000000000ffffffff0168bf000000000000160014751e76e8199196d454941c45d1b3a323f1433bd6000000000001012b50c3000000000000225120a60869f0dbcf1dc659c9cecbaf8050135ea9e8cdc487053f1dc6880949dc684c011340a2aad6c45bf977a99e4dad007c21a45c5d3f68f827156b8f480435d92709831656119df91a7cc3a217922259b1237ce68b8eeadba0c92dbd25635c3e20d9414f2116cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115190073c5da0a5600008000000080000000800000000000000000011720cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc1150000
由你的钱包组装
020000000001017fdd5301ea4116c966153c5b77d19e2cf8ace66ea61c3223a14401b6b87a56b90000000000ffffffff0168bf000000000000160014751e76e8199196d454941c45d1b3a323f1433bd60140a2aad6c45bf977a99e4dad007c21a45c5d3f68f827156b8f480435d92709831656119df91a7cc3a217922259b1237ce68b8eeadba0c92dbd25635c3e20d9414f00000000
69578e8043f5f24a4228f0519d2f18071865a8a16434ac784cd3dbd8c0b89764
多签
- 导入每个共同签名方的密钥:BitTool Signer 如何导出其 BIP48 共同签名方密钥,参见币种级页面(P2WSH 为
m/48'/0'/0'/2')。 - 构建 PSBT 时带上
witnessScript(P2SH-P2WSH 还需要redeemScript),并在每个输入上为每一个共同签名方密钥添加一条bip32Derivation。 - 依次发送给每个签名器,或者并行发送后再合并。BitTool Signer 只为它持有的密钥添加签名。如果一部手机在不同的钱包中持有两个共同签名方密钥,它会分别要求输入每个钱包的密码。
- 已有的签名会被验证并保留,因此 PSBT 可以按任意顺序流转。
BitTool Signer 会审核它被要求签名的脚本,但无法知道该策略是否符合用户的本意。请在创建多签钱包时,在你的钱包中展示完整的策略(门限、所有指纹)。