Estoy tratando de construir transacciones sin procesar desde cero para mejorar mi comprensión. A modo de comparación, estoy usando la salida hexadecimal de https://coinb.in/ ya que puedo elegir Testnet allí.
Estoy tratando de construir una transacción P2PKH sin Segwit (por ahora) que debería usar este tx 577735da1fccf6df79eac9ff42049a7729703ec5506efeb1602bca99df3bafd2
(índice 0) y enviar 6889990
satoshi a mv4rnyY3Su5gjcDNzbMLKBQkBicCtHUtFB
, la clave pública sin procesar de la dirección de entrada es034323ee9ac23504779b40c1b02578d27f70c12c22b7fc4f452dbbde681e45073d
Entonces, para la transacción sin firmar que produce mi biblioteca 0100000001d2af3bdf99ca2b60b1fe6e50c53e7029779a0442ffc9ea79dff6cc1fda357757000000002221034323ee9ac23504779b40c1b02578d27f70c12c22b7fc4f452dbbde681e45073dffffffff0106226900000000001976a9149f9a7abd600c0caa03983a77c8c3df8e062cb2fa88ac00000000
, que coincide con lo que produce coinb.
Entonces, para generar la firma para el sigscript, uso el siguiente código:
def sign_transaction(self, secrets):
"""
Sign all inputs of the transaction with
a secret key.
:param ECPrivKey[] secrets: a list of private keys corresponding to the inputs
:return: Transaction Signed version of the transaction ready to be published
"""
unsigned = bytes.fromhex(self.serialize_to_hex())
message = sha256(sha256(unsigned))
copy = deepcopy(self)
inputs = self.__inputs
for i in range(0, len(secrets)):
sk = secrets[i]
inp = inputs[i]
sig = SignatureFactory.gen_ecdsa_signature_bytes(message, sk)
copy.set_signature(sig)
sigscript = sig.get_asn1_encoded() + OP_SIGHASH_ALL
l = len(bytes.fromhex(sigscript))
script = compact_size_int(l) + sigscript + inp.get_sig_script()
copy.__inputs[i].set_sig_script(script)
return copy
De manera informal, uso la salida hexadecimal de la transacción sin firmar, la convierto en bytes, ejecuto dos funciones hash sha256 y agrego el byte SIGHASH ('01')
Validé la firma producida y es válida, así que siento que hay algún problema con la serialización. Aquí está mi transacción después de firmarla:
0100000001d2af3bdf99ca2b60b1fe6e50c53e7029779a0442ffc9ea79dff6cc1fda357757000000006a47304402207da5c1e2d7db828e415db1ae060d65e4a44de2b13b71c50be61d6c52da82425b022010da9abb70c7b6047b559c5c572f68e078d6ae78ba03dfd6aa1890e512e376760121034323ee9ac23504779b40c1b02578d27f70c12c22b7fc4f452dbbde681e45073dffffffff0106226900000000001976a9149f9a7abd600c0caa03983a77c8c3df8e062cb2fa88ac00000000
{"version": "01000000", "flag": "", "inputLen": "01", "inputs": [{"prevOutHash": "d2af3bdf99ca2b60b1fe6e50c53e7029779a0442ffc9ea79dff6cc1fda357757", "prevOutIx": "00000000", "sigScriptLen": "6a", "sigScript": "47304402207da5c1e2d7db828e415db1ae060d65e4a44de2b13b71c50be61d6c52da82425b022010da9abb70c7b6047b559c5c572f68e078d6ae78ba03dfd6aa1890e512e376760121034323ee9ac23504779b40c1b02578d27f70c12c22b7fc4f452dbbde681e45073d", "sequence": "ffffffff"}], "outputLen": "01", "outputs": [{"value": "0622690000000000", "pubKeyScriptLength": "19", "pubKeyScript": "76a9149f9a7abd600c0caa03983a77c8c3df8e062cb2fa88ac"}], "locktime": "00000000"}
En más detalle el valor de sigscript:
47 Script length
30 DER signature marker
44 Signature length
02 r value marker
20 r value length
7da5c1e2d7db828e415db1ae060d65e4a44de2b13b71c50be61d6c52da82425b r value
02 s value marker
2010da9abb70c7b6047b559c5c572f68e078d6ae78ba03dfd6aa1890e512e37676 s value
01 Opcode SIGHASH
21 pubkey length
034323ee9ac23504779b40c1b02578d27f70c12c22b7fc4f452dbbde681e45073d pubkey value
Si trato de transmitir la transacción en https://live.blockcypher.com/btc-testnet/pushtx/ obtengoError validating transaction: Error running script for input 0 referencing 577735da1fccf6df79eac9ff42049a7729703ec5506efeb1602bca99df3bafd2 at 0: Script was NOT verified successfully..
¿Alguien tiene una idea de lo que podría estar mal? Además, el valor r y s de la firma no lo codifiqué en little endian y no estoy seguro de si tal vez este podría ser el problema.
Firmar la transacción es un poco más complicado que simplemente firmar elhash of unsigned transaction
Mira las explicaciones aquí:
jakob abfalter
01000000 01 d2af3bdf99ca2b60b1fe6e50c53e7029779a0442ffc9ea79dff6cc1fda357757 00000000 19 76a9143ebad4eac79369b9c8fd6c3033386729a041f65d88ac ffffffff 01 0622690000000000 19 76a9149f9a7abd600c0caa03983a77c8c3df8e062cb2fa88ac 00000000
lamentablemente todavía no se valida.amaclin
jakob abfalter
amaclin