Nivel 5

P2SH (Pay-to-Script-Hash)

Bloquea fondos al hash de un script. El receptor define las condiciones, el emisor solo necesita la dirección.

El concepto

P2SH (Pay-to-Script-Hash), definido en BIP 16, introdujo una idea elegante: en vez de poner el script de bloqueo completo en el output, se pone solo su hash. El script completo (llamado redeemScript) se revela al gastar.

Las direcciones P2SH empiezan por "3" (como 3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy).

El problema que resuelve

Imagina un multisig 2-de-3. El script de bloqueo sería largo: OP_2 <pubKey1> <pubKey2> <pubKey3> OP_3 OP_CHECKMULTISIG

Son ~105 bytes solo para el scriptPubKey. El emisor tendría que conocer todas las claves públicas y construir este script.

Con P2SH:

  • El receptor construye el script complejo
  • Calcula su hash
  • Da al emisor una dirección corta basada en ese hash
  • El emisor envía a esa dirección sin conocer el script

El script de bloqueo (scriptPubKey)

OP_HASH160 <20 bytes: scriptHash> OP_EQUAL

En hexadecimal: a914<20 bytes scriptHash>87

Solo 23 bytes, independientemente de lo complejo que sea el redeemScript.

El script de desbloqueo (scriptSig)

<datos que satisfacen el redeemScript> <redeemScript>

El scriptSig incluye:

  1. Los datos necesarios para satisfacer el redeemScript (firmas, etc.)
  2. El redeemScript completo

Ejecución

La validación ocurre en dos fases:

Fase 1: Verificar el hash

Push <datos> (ignorados en esta fase) Push <redeemScript> OP_HASH160 Pila: [datos..., hash(redeemScript)] Push <scriptHash> Pila: [datos..., hash(redeemScript), expectedHash] OP_EQUAL ¿hash(redeemScript) == expectedHash? Pila: [datos..., TRUE/FALSE]

Si el hash no coincide, falla inmediatamente.

Fase 2: Ejecutar el redeemScript

Si la fase 1 pasa (el hash coincide), el redeemScript se "deserializa" y ejecuta con los datos proporcionados.

Es como si el redeemScript fuera el scriptPubKey original, y los datos anteriores fueran el scriptSig.

Ejemplo: P2SH-Multisig

RedeemScript para 2-de-3: OP_2 <pubKey1> <pubKey2> <pubKey3> OP_3 OP_CHECKMULTISIG

Para gastar, el scriptSig sería: OP_0 <sig1> <sig2> <redeemScript>

(El OP_0 al inicio es por un bug histórico en OP_CHECKMULTISIG que consume un elemento extra de la pila.)

El receptor calcula: scriptHash = HASH160(redeemScript)

Y da al emisor una dirección derivada de ese hash.

P2SH-P2WPKH: SegWit envuelto

Cuando SegWit se activó, muchas wallets y servicios no lo soportaban. P2SH permitió una transición gradual:

El redeemScript es simplemente: OP_0 <20 bytes pubKeyHash>

Esto indica un witness program versión 0. El nodo reconoce que debe buscar los datos de firma en el witness, no en el scriptSig.

Desde fuera, parece una transacción P2SH normal (dirección empieza por 3). Pero internamente usa SegWit.

Esto permitió a usuarios con wallets SegWit recibir de servicios que solo soportaban direcciones legacy o P2SH.

Limitaciones de P2SH

Tamaño del redeemScript

El redeemScript completo debe caber en el scriptSig, que tiene límites de tamaño. Para scripts muy complejos, esto puede ser un problema.

Revelación completa

Al gastar, revelas TODO el redeemScript. Si tienes un esquema con múltiples condiciones alternativas, todas se revelan aunque solo uses una.

Taproot resuelve esto con MAST: solo revelas la rama que usas.

Fees

El redeemScript va en el scriptSig, que cuenta como datos "base" (4 WU/byte). P2WSH (SegWit nativo) pone el script en el witness (1 WU/byte), resultando en fees menores.

Direcciones P2SH

Las direcciones P2SH usan Base58Check con prefijo 0x05 para mainnet:

  1. scriptHash (20 bytes)
  2. Prefijo: 0x05
  3. Checksum: SHA256(SHA256(...))[0:4]
  4. Concatenar y codificar en Base58

El resultado empieza por "3".

Cuándo usar P2SH hoy

  • P2SH-P2WPKH: si necesitas compatibilidad con sistemas que no soportan bc1q
  • Multisig legacy: aunque P2WSH es preferible para nuevos setups
  • Compatibilidad con contratos existentes

Para nuevos usos, SegWit nativo (P2WSH) o Taproot son preferibles.