Wallets y autocustodia

PSBT: transacciones parcialmente firmadas

Qué viaja exactamente entre tu ordenador y tu firmador: los seis roles de BIP-174, los campos que importan, por qué el firmante pide la transacción previa, qué comprueba antes de firmar, qué cambian las versiones 2 y Taproot y qué revela un PSBT de ti.
En este artículo

¿Qué viaja exactamente entre tu ordenador y tu firmador?

Un firmador que no ve la cadena de bloques no puede saber cuánto vale lo que gastas. Todo lo que sabe de importes, scripts y cambio se lo cuenta el ordenador que prepara la transacción. Ese ordenador puede estar comprometido. El formato que lleva esa información de un lado a otro es el PSBT (Partially Signed Bitcoin Transaction), definido en BIP-174 por Ava Chow.

Un PSBT es la transacción a medio hacer más lo que cada firmante necesita para comprobarla sin consultar nada más: los UTXO que gasta, los scripts, las rutas de derivación de cada clave con la huella de su seed y las firmas que ya hay. Por qué se firma sin conexión y por qué canal viaja (QR, microSD) está en firmar sin conexión. Aquí se abre el contenedor.

Una aclaración histórica. La multifirma se usa desde 2012, cuando BIP-11 y P2SH (BIP-16) la hicieron estándar, y nadie necesitó el PSBT para inventarla. Lo que aportó BIP-174 fue un formato común. Antes, según su propia motivación, crear transacciones sin firmar o parcialmente firmadas para pasarlas entre varios firmantes dependía de cada implementación. Un programa no sabía leer lo que escribía otro. El BIP también se propuso que los firmantes sin conexión, como las hardware wallets, puedan firmar sin acceso al conjunto de UTXO y sin riesgo de que los engañen. Esa segunda promesa se cumple a medias, como se verá.

Los seis roles de BIP-174

El BIP no describe aplicaciones, describe papeles. Un mismo programa suele hacer varios, y cada papel solo hace lo suyo.

  • Creador (Creator). Crea el PSBT con la transacción sin firmar y los mapas de entradas y salidas vacíos.
  • Actualizador (Updater). Añade lo que sabe: el UTXO de cada entrada, los scripts y las rutas BIP-32. El propio BIP dice que lo normal es que una misma entidad sea creador y actualizador.
  • Firmante (Signer). Comprueba, firma y añade su firma como firma parcial. Solo puede usar los UTXO que trae el PSBT y solo añade datos: no borra ni reescribe nada. No tiene por qué saber firmar todos los tipos de entrada.
  • Combinador (Combiner). Junta varios PSBT de la misma transacción en uno. No necesita entender los scripts. Nunca mezcla dos transacciones distintas.
  • Finalizador de entradas (Input Finalizer). Cuando una entrada ya tiene todo lo necesario, construye su scriptSig y su witness definitivos y borra los datos intermedios. Falla si alguna firma no usa el tipo de firma (sighash) pedido en el PSBT.
  • Extractor (Transaction Extractor). Si todas las entradas están finalizadas, saca la transacción serializada lista para la red. El BIP dice que lo normal es que finalizador y extractor sean la misma entidad.

Esa separación explica errores comunes. Un PSBT con todas las firmas parciales todavía no es una transacción de red: falta finalizar y extraer. Y el firmante nunca difunde nada, porque no es su papel.

Ejemplo 1: billetera vigía y una hardware wallet

La configuración más común. Un ordenador tiene una billetera (wallet) vigía (watch-only), que ve los fondos pero no puede gastarlos, y un aparato guarda las claves. El reparto de papeles es este.

  1. El ordenador (Sparrow, Bitcoin Core u otro) hace de creador y actualizador. Elige UTXO, salidas y comisión. Añade a cada entrada el UTXO que gasta y la ruta BIP-32 de su clave, y a la salida de cambio también su ruta.
  2. El aparato hace de firmante. Comprueba, enseña la transacción en su pantalla, firma y devuelve el PSBT con la firma parcial. Si con su firma ya no falta ninguna, algunos firmadores también finalizan: la Coldcard, por ejemplo, guarda entonces en la microSD, junto al PSBT firmado, la transacción final lista para difundir.
  3. El ordenador hace de finalizador y extractor: monta el witness, extrae la transacción y la difunde.

En Bitcoin Core el recorrido tiene nombre propio: walletcreatefundedpsbt, luego la firma del aparato (o walletprocesspsbt si la clave está en Core), luego finalizepsbt y por último sendrawtransaction. La orden analyzepsbt dice en qué punto está el PSBT, qué rol toca a continuación y estima comisión y peso.

Ejemplo 2: multifirma 2 de 3, en serie o en paralelo

Un descriptor wsh(sortedmulti(2,A,B,C)) exige dos firmas de tres claves. El coordinador crea y actualiza: en cada entrada pone el UTXO, el script de testigo (el propio 2 de 3) y las rutas de las tres claves. Puede añadir las tres xpub en el mapa global. En la salida de cambio pone su propio script de testigo, con la misma política 2 de 3 pero con las claves de la rama de cambio, y las tres rutas, para que cada firmante lo reconozca.

En serie. El PSBT va al aparato A, que añade su firma. Ese resultado va a B, que añade la suya. Es el flujo en serie que cuenta firmar sin conexión.

En paralelo. El mismo PSBT sin firmar va a A y a B por separado, por ejemplo a dos personas en dos ciudades. Cada una devuelve el suyo. El combinador los junta. BIP-174 garantiza que el orden da igual: combinar A con B es lo mismo que combinar B con A, salvo que haya campos en conflicto. Para eso existe este rol.

El finalizador monta entonces el witness de una entrada de 2 de 3. Son cuatro elementos: uno vacío, que exige la regla NULLDUMMY (BIP-147) por un fallo antiguo de OP_CHECKMULTISIG, las dos firmas en el orden de las claves dentro del script y el propio script de testigo. Después borra los campos intermedios y el extractor saca la transacción. La tercera clave, C, no ha intervenido. Cuántas firmas piden, cómo se reparten y cómo se recupera esa configuración está en diseño de una multifirma.

Qué lleva dentro

Un PSBT empieza por los bytes 70 73 62 74 FF: «psbt» en ASCII y un 0xFF que hace que un lector de transacciones normales falle con él, y al revés. Por eso el Base64 de cualquier PSBT empieza por cHNidP8 y su hexadecimal por 70736274ff. Después vienen tres tipos de mapas de pares clave-valor: uno global, uno por cada entrada y uno por cada salida. Cada mapa acaba en un byte 0x00.

Estos son los campos de la versión 0 que importan al lector, con su código entre paréntesis.

Campo (código)Para qué sirve
Mapa global
UNSIGNED_TX (0x00)La transacción sin firmar, con scriptSig y witness vacíos. Obligatoria en v0.
XPUB (0x01)Una xpub con su huella y su ruta, útil en multifirma.
Mapa de cada entrada
NON_WITNESS_UTXO (0x00)La transacción previa entera.
WITNESS_UTXO (0x01)Solo la salida que se gasta: importe y script.
PARTIAL_SIG (0x02)La firma de un firmante.
SIGHASH_TYPE (0x03)El tipo de firma que se pide.
REDEEM_SCRIPT (0x04), WITNESS_SCRIPT (0x05)Los scripts que hay que presentar al gastar.
BIP32_DERIVATION (0x06)Clave pública, huella de la clave maestra y ruta.
FINAL_SCRIPTSIG (0x07), FINAL_SCRIPTWITNESS (0x08)El resultado del finalizador.
Mapa de cada salida
REDEEM_SCRIPT (0x00), WITNESS_SCRIPT (0x01), BIP32_DERIVATION (0x02)Lo que permite al firmante reconocer el cambio.

Además hay un tipo propietario (0xFC) para datos que solo entiende quien los puso. La regla de extensibilidad es sencilla: un firmante que encuentra pares que no entiende debe dejarlos pasar tal cual. Los campos nuevos se añaden en BIPs aparte.

Para ver un PSBT de verdad, el decodificador de Bitcoinpedia trae como ejemplos cuatro PSBT de los vectores públicos de BIP-174 y BIP-370. Ninguno lleva claves privadas.

Por qué el firmante pide la transacción previa

La diferencia entre WITNESS_UTXO y NON_WITNESS_UTXO parece una nimiedad de tamaño. No lo es. Es la diferencia entre fiarse del ordenador y comprobarlo.

En una entrada no SegWit, la firma no incluye el importe de lo que se gasta. El firmante necesita la transacción previa entera, calcula su hash y lo compara con el TXID que se gasta. Si cuadra, el importe es el verdadero, porque el hash lo ata. BIP-174 lo exige a los firmantes de esas entradas.

En SegWit v0 (BIP-143), cada firma incluye el importe de su propia entrada, pero no el de las demás. Entonces WITNESS_UTXO es solo una afirmación del coordinador. De ahí viene la CVE-2020-14199, publicada el 16 de junio de 2020. Un ejemplo con números inventados, para verlo: dos entradas, A de 0,30 BTC y B de 0,20 BTC, y unas salidas que suman 0,3499 BTC. La comisión real es de 0,1501 BTC, pero el ordenador no lo dice.

  1. Pide firmar diciendo que B vale 0,05 BTC. El firmante ve entradas por 0,35, salidas por 0,3499 y una comisión normal de 0,0001. La firma de A es válida, porque el importe de A es el verdadero. La de B no lo es.
  2. Pide firmar de nuevo diciendo que A vale 0,15 BTC. El firmante ve otra vez una comisión de 0,0001. Ahora la firma de B es válida y la de A no.
  3. El ordenador junta las dos firmas válidas. Resulta una transacción real que regala 0,1501 BTC a los mineros, o a un minero compinchado con el atacante.

Ver la misma comisión en pantalla las dos veces no protege, porque el truco está en juntar las firmas. La respuesta de Trezor fue exigir la transacción previa entera también en entradas SegWit, lo que rompió la compatibilidad con billeteras que no la mandaban. Bitcoin Optech (boletín 101, 10 de junio de 2020) cuenta que ese cambio puede suponer un aumento notable de datos. Trezor lo corrigió en los firmwares 1.9.1 (Trezor One) y 2.3.1 (Model T), y Ledger publicó su boletín LSB-010 el 3 de junio de 2020, corregido en la app Bitcoin 1.4.0. La regla de «no firmes dos veces» y cómo lo resolvió cada fabricante están en firmar sin conexión.

Bitcoin Core 0.20.1 (1 de agosto de 2020) hizo que sus PSBT lleven los dos campos en las entradas SegWit: la transacción previa entera para las billeteras que ahora la exigen y la salida sola para las que se apoyaban en ella para saber que la entrada era SegWit. BIP-174 permite llevar los dos a la vez justamente por esto.

La solución de fondo la propuso Johnson Lau en agosto de 2018: que la firma se comprometa con los importes de todas las entradas. Es lo que hace la firma de Taproot (BIP-341), salvo que use ANYONECANPAY. Por eso BIP-371 admite la WITNESS_UTXO sola en las entradas Taproot. Las entradas SegWit v0 de la misma transacción siguen necesitando la transacción previa.

Qué comprueba el firmante antes de firmar

La lista de qué mirar en la pantalla del aparato está en firmar sin conexión. Esta es la parte de dentro: lo que hace el aparato para que esa pantalla sea fiable.

  • Integridad. Que el hash de la transacción previa sea el del prevout que se gasta, que el script de canje y el de testigo cuadren con el scriptPubKey, y que no haya campos mal formados. Si algo falla, el PSBT se rechaza.
  • Importes y comisión. La comisión es la suma de las entradas menos la suma de las salidas. Solo es fiable si los importes de entrada están atados: por la transacción previa o, si todas las entradas son Taproot, por la propia firma.
  • Cambio. La ruta de una salida la escribe el coordinador, así que por sí sola no prueba nada. El firmante mira si la huella es suya, deriva él mismo la clave en esa ruta y comprueba que es la de la salida. En multifirma reconstruye la política de las entradas que firma (cuántas claves, en qué orden, cuántas hacen falta) y exige que la salida tenga la misma. BIP-174 presenta esta comprobación como opcional, pero es la que impide que una salida del atacante pase por cambio. Una salida que no se reconoce como cambio se trata como un pago externo y se enseña. La defensa completa es registrar la política completa en el aparato, como explica hardware wallets con BIP-388.
  • Tipo de firma. Si el PSBT pide un sighash raro (NONE, SINGLE, ANYONECANPAY), el firmante debe rechazar o avisar. Una firma así deja cambiar partes de la transacción después. Sin sighash indicado, BIP-174 recomienda firmar con SIGHASH_ALL.
  • Rutas raras. Si el cambio va a otra cuenta o a un índice muy alto, el aparato debe avisar: es una de las alertas que lista firmar sin conexión. Con un índice muy alto, además, la billetera vigía puede no ver esos fondos, porque las billeteras dejan de buscar direcciones tras una racha sin usar (el límite de huecos o gap limit, que BIP-44 fija en 20 para las de recepción y que en las de cambio cada programa elige).

Versiones y extensiones

PSBT v2 (BIP-370). En v0, la transacción global fija impedía añadir entradas o salidas después de crear el PSBT. La v2 elimina esa limitación: no lleva UNSIGNED_TX y cada entrada y cada salida lleva sus propios datos. Aparece un séptimo papel, el constructor (Constructor), que añade entradas y salidas mientras un campo global (TX_MODIFIABLE) lo permita. Al firmar, el firmante cierra las entradas, salvo que firme con ANYONECANPAY, y las salidas, salvo que firme con SIGHASH_NONE. Sirve cuando varias partes añaden entradas y salidas a la misma transacción, o cuando una salida no se puede calcular hasta tener todas las entradas. Es el caso de los pagos silenciosos con BIP-375, que depende de la v2 y sigue en borrador a 7 de octubre de 2026. Core Lightning ya la usa, según el hilo de bitcoindev de enero de 2025. PayJoin, en cambio, sigue con la versión 0 (BIP-77). La v2 no se llama «versión 1», porque a la v0 se la llamaba así coloquialmente y se saltó el número.

La v2 no es compatible con la v0, a propósito. Se puede convertir una v2 en v0 construyendo la transacción sin firmar. Para una firma o una multifirma normal no cambia nada, salvo una cosa práctica: coordinador y firmador tienen que entender la misma versión. Ledger lee v2 desde la app 2.0.0, de 2021 (sus bibliotecas convierten la v0 a v2 por su cuenta), según su desarrollador Salvatore Ingala en el hilo de bitcoindev del 17 de enero de 2025. Sobre el resto de aparatos no hay aquí una lista contrastada, así que conviene comprobar el tuyo.

Eso importa por un cambio cercano. La 32.0 de Bitcoin Core, aún sin publicar a 7 de octubre de 2026 (su tercera versión candidata, rc3, es del 1 de octubre), creará PSBT v2 por defecto con createpsbt, walletcreatefundedpsbt, converttopsbt y psbtbumpfee, según su borrador de notas, con un argumento psbt_version para pedir v0. La implementación (PR #21283) se fusionó en Core el 5 de mayo de 2026. Si el firmador no lee v2, habrá que pedir v0 a mano.

Taproot (BIP-371). Sirve para v0 y v2. Añade campos para la firma Schnorr (TAP_KEY_SIG, TAP_SCRIPT_SIG) y para esconder scripts: clave interna, árbol y bloque de control. Al firmante le importan dos cosas: que en sus entradas Taproot basta WITNESS_UTXO, y que reconoce el cambio Taproot por la clave interna y la ruta de derivación de la salida. Core lo admite desde la 24.0.

MuSig2 (BIP-373). Añade cuatro campos y obliga a que el PSBT dé dos vueltas: primero cada firmante añade su nonce y, cuando están todos, cada uno añade su firma parcial. Core lo admite desde la 30.0. El detalle y sus riesgos están en MuSig2 y FROST.

Formatos

Un PSBT se guarda en binario, como fichero con extensión .psbt (lo que va en una microSD), o en Base64, el texto que empieza por cHNidP8 y que se copia y pega o se pasa a las órdenes de Core. El hexadecimal lo usan algunas herramientas, pero BIP-174 no lo define como codificación. Los QR (UR o BBQr) también son codificaciones, y se explican en firmar sin conexión. Ninguno cifra nada.

Qué revela un PSBT

Sin firmas, un PSBT no permite gastar. Pero no es secreto, y suele ser un error tratarlo como si lo fuera. Lleva las entradas y las transacciones previas, y por ellas parte de tu historial; los importes; cuál es el cambio; las huellas de tus seeds; las rutas de derivación y, si incluye el campo global de xpub, tus xpub. Con una xpub se ve el saldo y el historial de toda la cuenta, como explica HD wallets y xpub. Las entradas y las transacciones que expone ya cuentan mucho de ti.

También puede llevar datos más delicados. BIP-174 tiene campos para preimágenes de hash (0x0a a 0x0d), que sirven para gastar scripts con hashlock, como un HTLC o algunos contratos de Miniscript. En esos scripts la preimagen es justo el secreto que desbloquea, así que, si el PSBT la lleva, quien lo vea antes de que se difunda la transacción la conoce. Y el tipo propietario puede llevar datos que solo entiende quien los puso: el firmante los deja pasar sin mirarlos.

Dos consecuencias prácticas. No pegues un PSBT en un decodificador de una web ajena: el de Bitcoinpedia se ejecuta en tu navegador, pero eso no te dice nada de los demás. Y quien fotografíe el QR ve la transacción. Un PSBT firmado del todo, por último, es una transacción lista: cualquiera que lo tenga puede difundirla, aunque no pueda cambiarla si las firmas usan SIGHASH_ALL.

Qué significa esto para ti

Un PSBT no es una billetera ni una app: es un estándar, y el mismo fichero lo lee cualquier programa que implemente la misma versión. Lo que aporta es interoperabilidad entre un coordinador y un firmador de marcas distintas. La seguridad no la da el formato: sigue dependiendo de que el firmador compruebe importes y cambio por su cuenta y de que tú leas su pantalla.

Comprueba qué versión crea tu coordinador y cuál lee tu firmador, sobre todo cuando Core 32.0 salga. Trata cada PSBT como un dato privado, aunque no lleve claves. En multifirma, distingue firmar en serie de firmar en paralelo y combinar: el segundo método evita que el fichero pase de mano en mano. Y, para practicar, abre un vector de BIP-174 en la herramienta de Bitcoinpedia y localiza las entradas, las salidas, la comisión y las firmas que faltan. El diseño de la multifirma que te interesa está en diseño de una multifirma y la sintaxis de los descriptores en descriptores de salida.

Errores habituales

  • Creer que PSBT hizo posible la multifirma: se usa desde 2012, cuando BIP-11 y P2SH (BIP-16) la hicieron estándar. PSBT la hizo interoperable entre programas distintos.
  • Pensar que un PSBT es una billetera o un fichero de Sparrow, de Coldcard o de Core: es un estándar (BIP-174), y lo lee cualquiera que implemente la misma versión.
  • Creer que la firma se hace siempre en fila, uno tras otro: se puede firmar en paralelo y juntar los PSBT con el combinador.
  • Confundir un PSBT con todas las firmas con la transacción lista: falta que el finalizador monte el witness y el extractor saque la transacción. Hasta entonces, no es una transacción de red.
  • Creer que las rutas BIP-32 del PSBT prueban que el cambio es tuyo: las pone el coordinador. Lo prueba el firmante derivando la clave y, en multifirma, comprobando la política.
  • Dar por hecho que en SegWit el firmante ya conoce todos los importes: solo conoce el de la entrada que firma (BIP-143). De ahí el ataque de 2020 y la transacción previa.
  • Suponer que la versión 2 sustituye a la 0 y que todo el mundo la lee: no son compatibles entre sí, y Core 32.0 (aún sin publicar a 7 de octubre de 2026) creará v2 por defecto.
  • Pensar que un PSBT es privado porque no lleva claves privadas: lleva importes, historial, huellas, rutas y a veces xpub.
  • Creer que el Base64 o el QR cifran el PSBT: son codificaciones.

Conceptos relacionados

Fuentes primarias

  1. Ava Chow, «BIP-174: Partially Signed Bitcoin Transaction Format» (2017, v1.4.4)
  2. Ava Chow, «BIP-370: PSBT Version 2» (2021)
  3. Ava Chow, «BIP-371: Taproot Fields for PSBT» (2021)
  4. Ava Chow, «BIP-373: MuSig2 PSBT Fields» (2024)
  5. BIP-375: Sending Silent Payments with PSBTs (borrador, 2025)
  6. BIP-143: Transaction Signature Verification for Version 0 Witness Program
  7. BIP-341: Taproot, nota sobre los importes de todas las entradas
  8. BIP-44: Multi-Account Hierarchy for Deterministic Wallets, «Address gap limit»
  9. BIP-77: Async Payjoin
  10. Bitcoin Core, «doc/bips.md» (consultado el 7 de octubre de 2026)
  11. Bitcoin Core, «doc/psbt.md» (consultado el 7 de octubre de 2026)
  12. Bitcoin Core 0.20.1, notas de versión, «PSBT changes» (1 de agosto de 2020)
  13. Bitcoin Core, PR #21283, soporte de PSBT v2 (fusionada el 5 de mayo de 2026)
  14. Bitcoin Core, «32.0 Release Notes Draft» (borrador, consultado el 7 de octubre de 2026)
  15. Bitcoin Core, etiqueta v32.0rc3 (1 de octubre de 2026)
  16. CVE.org, «CVE-2020-14199» (16 de junio de 2020)
  17. NVD, «CVE-2020-14199» (publicada el 16 de junio de 2020)
  18. Ledger Donjon, «LSB-010: Massive transaction fees in BTC app and derivative» (3 de junio de 2020)
  19. Bitcoin Optech, «Newsletter #101» (10 de junio de 2020)
  20. Sjors Provoost, hilo «Who uses or wants to use PSBTv2 (BIP370)», bitcoindev (17 de enero de 2025)
  21. Coldcard, firmware, «shared/auth.py» (consultado el 7 de octubre de 2026)