Generar y enviar transacciones de Bitcoin sin procesar

Cuando intento enviar una transacción de Bitcoin sin procesar a través de la API de blockchain.info, recibo el siguiente mensaje de error:

El script resultó en una pila no verdadera: []

La transacción debe enviar 0,001 Bitcoins con una tarifa de 0,0005 desde 1CBzN3YW4h7XRwb5sjpmBSEPmVPa9wHPgD hasta 1KAsr5RcApYG1Rk9uLwsHTXvwsyD1FVyFy.

transacción sin firmar:

01000000
01
88802ffe48d0f9d2867495e933b1477094ce017f5d6e4204e40f1040ab805c16
00000000
19
76a9147abd6d64781930ee9abfaa75b0976b45ce9b93ba88ac
ffffffff
01
a086010000000000
19
76a914c75073b564d6ebce3d5d12d59ab20d44bd10f69f88ac
00000000
01000000

transacción firmada:

01000000
01
88802ffe48d0f9d2867495e933b1477094ce017f5d6e4204e40f1040ab805c16
00000000
8b
483045022100FA512B36C030BAD0868E2679E1B29E32CCE0099DA086F8FD82010DFFF61B79BA02206C00220683E448C29CCE73FCD7F3CD74E3F76582C07F2F0B436EF247C2D2523F014104a75429241bc8c83e0a1c615155e9b984880f16d39b09b28eef464139fb84d8ff507a5d482e8f41cdb5a762436515d310f16b208bdce4ddfb8a30a7236d36a2da
ffffffff
01
a086010000000000
19
76a914c75073b564d6ebce3d5d12d59ab20d44bd10f69f88ac
00000000

¿Alguien tiene una idea de por qué la transacción es incorrecta?

¿Puede proporcionar la transacción de crédito que gasta en formato hexadecimal? ¿Preferiblemente sin los saltos de línea que está usando en los otros? ¿Supongo que falla en el intérprete de alguna manera?
¿Te refieres a la salida que se gastará? El hexadecimal de la salida no gastada es: 76a9147abd6d64781930ee9abfaa75b0976b45ce9b93ba88ac, script: OP_DUP OP_HASH160 7abd6d64781930ee9abfaa75b0976b45ce9b93ba OP_EQUALVERIFY OP_CHECKSIG.

Respuestas (4)

algo está mal en su scriptSig

la clave pública en su secuencia de comandos es

04a75429241bc8c83e0a1c615155e9b984880f16d39b09b28eef464139fb84d8ff507a5d482e8f41cdb5a762436515d310f16b208bdce4ddfb8a30a7236d36a2daf 

pero no coincide con la dirección https://blockchain.info/address/1CBzN3YW4h7XRwb5sjpmBSEPmVPa9wHPgD que es la salida de https://blockchain.info/tx/165c80ab40100fe404426e5d7f01ce947047b133e9957486d2f9d048fe2f8088

¿Está seguro de que está firmando con la clave privada de 1CBzN3YW4h7XRwb5sjpmBSEPmVPa9wHPgD?

La clave pública correcta es: 04a75429241bc8c83e0a1c615155e9b984880f16d39b09b28eef464139fb84d8ff507a5d482e8f41cdb5a762436515d310f16b208bdce4ddfb8a30a7236d36a. Había una 'f' adicional al final que debería haber estado en la línea de abajo: 'ffffffff'.

Pude enviar la transacción después de firmarla a través de https://coinb.in/#sign .

Parece que estoy generando firmas incorrectas.

Usé el siguiente código para producir una firma correcta:

public String sign(String msg, BigInteger d) throws IOException {
    ECDSASigner signer = new ECDSASigner();
    X9ECParameters params = SECNamedCurves.getByName("secp256k1");
    ECDomainParameters ecDomainParameters = new ECDomainParameters(params.getCurve(), params.getG(), params.getN(), params.getH());
    ECPrivateKeyParameters ecPrivateKeyParameters = new ECPrivateKeyParameters(d, ecDomainParameters);
    signer.init(true, ecPrivateKeyParameters);
    BigInteger[] sigs = signer.generateSignature(DatatypeConverter.parseHexBinary(msg));
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    DERSequenceGenerator seq = new DERSequenceGenerator(byteArrayOutputStream);
    seq.addObject(new DERInteger(sigs[0]));
    seq.addObject(new DERInteger(sigs[1]));
    seq.close();
    byte[] bytes = byteArrayOutputStream.toByteArray();
    return DatatypeConverter.printHexBinary(bytes);

}

Ingresé su transacción sin procesar sin firmar en el archivo y seguí estos pasos:

1.) crear el tx en bruto sin firmar y el hash doble

printf "010000000188802ffe48d0f9d2867495e933b1477094ce017f5d6e4204e40f1040ab805c16000000001976a9147abd6d64781930ee9abfaa75b0976b45ce9b93ba88acffffffff01a0860100000000001976a914c75073b564d6ebce3d5d12d59ab20d44bd10f69f88ac0000000001000000" > tmp_urtx.txt
xxd -r -p <tmp_urtx.txt >tmp_urtx.hex
# if no xxd (OpenBSD, FreeBSD ...), then this:
# result=$( cat tmp_urtx.txt | sed 's/[[:xdigit:]]\{2\}/\\x&/g' )
# printf $result > tmp_urtx.hex
openssl dgst -binary -sha256 >tmp_sha256.hex <tmp_urtx.hex
openssl dgst -binary -sha256 >tmp_dsha256.hex <tmp_sha256.hex
xxd -ps tmp_dsha256.hex | tr -d "\n" > tx_hash.txt
xxd -r -p <tx_hash.txt >tx_hash.hex

2.) crear el pubkey.pem

echo 3056301006072a8648ce3d020106052b8104000a034200 > pubkey.txt
echo 04a75429241bc8c83e0a1c615155e9b984880f16d39b09b28eef464139fb84d8ff507a5d482e8f41cdb5a762436515d310f16b208bdce4ddfb8a30a7236d36a2da >> pubkey.txt
xxd -r -p <pubkey.txt | openssl pkey -pubin -inform der >pubkey.pem
openssl asn1parse -in pubkey.pem

3.) crear el archivo de firma

echo 3045022100FA512B36C030BAD0868E2679E1B29E32CCE0099DA086F8FD82010DFFF61B79BA02206C00220683E448C29CCE73FCD7F3CD74E3F76582C07F2F0B436EF247C2D2523F > tx_sig.txt
xxd -r -p <tx_sig.txt >tx_sig.hex

4.) verificar todos juntos

openssl pkeyutl <tx_hash.hex -verify -pubin -inkey pubkey.pem -sigfile tx_sig.hex

--> Fallo de verificación de firma

5. Conclusión

como no coincide, el enlace entre privkey, signature y pubkey parece ser incorrecto. Verifiqué dos veces la firma, aunque parece correcta:

#########################################################
### procedure to strictly check DER-encoded signature ###
#########################################################
Minimum and maximum size constraints                        - ok
scriptsig always starts with 0x30                           - ok
length 138 chars is less than actual sig length (142 chars) - ok
       (hex 0x45, decimal 69, 138 chars)
length of R coordinate (66) >= 0                            - ok
length of S coordinate (64) >= 0                            - ok
S-Value is within scriptsig boundaries                      - ok
Make sure the R & S length covers the entire signature      - ok
S-value must be smaller than N/2                            - ok
strictly check DER-encoded signature                        - ok
#########################################################

¿Quizás verifique dos veces entre priv y pubkeys? (¿comprimido y sin comprimir?)