He estado siguiendo BIP16 en la creación de una transacción P2SH. Quiero crear un P2SH simple (una firma). Recibo un error al intentar transmitir el tx. El error es16: mandatory-script-verify-flag-failed (Signature must be zero for failed CHECK(MULTI)SIG operation)
Para ser claros, no estoy intentando multisig. Lo que estoy haciendo se puede describir mejor como P2SH-P2PK
, aunque no he visto este término. Este es el único ejemplo dado en BIP16, por lo que debería funcionar.
Esto es lo que he probado (testnet):
private key: BB2AC60BC518C0E239D5AF9D8D051A6BDFD0D931268DCA70C59E5992
public key: 039f53e45f8f18b8ed294378bda342eff69b2053debf27fbede7d2d6bd84be6235
(compressed)
redeemScript: [{pubKeySize,pubKey}] [OP_CHECKSIG]
21039F53E45F8F18B8ED294378BDA342EFF69B2053DEBF27FBEDE7D2D6BD84BE6235AC
redeemScriptHash: RIPEMD160(SHA256(redeemScript))
323D0E8A083E98010299109337850D05DD6157F7
p2shAddress: Base58Check(0xC4 + redeemScriptHash) (C4 for testnet)
2MwprvB9tUMtX4vK8zJK8K329fNu79CJgR7
La dirección anterior tiene dos UTOX en testnet:
UTXO1: e434a13cac79dc3d26e7279bff05c0f071a2df03e2ba6ca13c88f0e82dca9998:0
UTXO2: 9b4943e7ab5f4512e42c94254eb6aab4c6823ce06d4ff816b7ce4fda155a2571:0
Ahora quiero gastar ambos UTXO y seguir con los siguientes resultados:
Out1: 2MwprvB9tUMtX4vK8zJK8K329fNu79CJgR7 34000000 Satoshis
Out2: 2N8hwP1WmJrFF5QWABn38y63uYLhnJYJYTF 100000000 Satoshis
Creé el tx de la siguiente manera:
Cree transacciones sin firmar con todos los scriptSigs vacíos
Para que cada entrada se firme, configure su scriptSig para redimirScript: 21039F53E45F8F18B8ED294378BDA342EFF69B2053DEBF27FBEDE7D2D6BD84BE6235AC
, manteniendo otros scriptSigs vacíos.
Serialice el nuevo tx y agregue los bytes SIGHASHALL (0x01) en little endian 4 bytes
Doble Sha256 arriba y firme el valor resultante. Agregue un byte 0x01 a la firma para indicar SIGHASH_ALL. Sea sig
el valor resultante.
Establezca scriptSig como:
[0x00] [{sigSize, sig}] [{pubKeySize, pubKey}] [OP_CHECKSIG]
Supongo que se usará el siguiente scriptPubKey:
[OP_HASH160] [{scriptHashSize, scriptHash}] [OP_EQUAL]
Los siguientes son los valores y k
para la firma de cada entrada:r
s
Entrada 1:
k = 98790447509501799195296257240616657470656053786701275200434341714298778299820
r = 96398386359095408146340664941016369169423137684113382189227162443480418477689
s = 62903510511574365450545635776206168644738316078298063260649088246548574249129
Entrada 2:
k = 109372172176680138721552873719725202562296645126925021083510279924852033069204
r = 105162394984132461723584277789901247831150698039237112243693144757926439529504
s = 62903510511574365450545635776206168644738316078298063260649088246548574249129
Después de esto, recibo el siguiente error en bitcoind para enviar el tx:
error code: -26
error message:
16: mandatory-script-verify-flag-failed
(Signature must be zero for failed CHECK(MULTI)SIG operation)
¿Qué estoy haciendo mal?
EDITAR: Gracias a la respuesta de arubi, descubrí que había dos problemas con los pasos anteriores. Lo primero que estaba haciendo mal era no codificar los redeemScript
datos de la pila. [0x00]
En segundo lugar , lo que estaba haciendo mal era poner scriptSig
. Después de arreglar eso, el Paso 5 debería ser:
Establecer redeemScript
como[{pubKeySize, pubKey}] [OP_CHECKSIG]
Establecer scriptSig
como[{sigSize, sig}] [{redeemScriptSize, redeemScript}]
El problema es que scriptsig contiene el script redimido real en lugar del script serializado como una inserción. El segundo error, el script de redención contiene un 0x00
valor extraño que no debería estar allí, ya que se trata de un simple CHECKSIG
.
arubí
0x00
valor que queda en la pila no invalida la transacción, sino que no se detectará antes de la retransmisión por la política local, ya que no se adhiere a lacleanstack
regla.Jus12
0x00
, ¿se considerará válido?arubí
OP_CHECKSIG
último que se ejecuta empujará un valor que se evalúa como Verdadero (0x01
en este caso) a la parte superior de la pila. La pila será: 0x01 0x00 Hacer que todo el script se evalúe como Verdadero.