Verificación de firma de Bitcoin

Estoy tratando de implementar el código de operación OP_CHECKSIG de Bitcoin y verificar si una firma es válida o no. Tengo la firma que recibo de los datos de la transacción y la clave pública (el campo hexadecimal de una transacción P2PKH debe contener ambos). Estoy tratando de averiguar cuál es el resumen del mensaje que está firmado. Por lo que sé, estos son los elementos necesarios:

1. El número de versión (4 bytes)
2. El número de Entradas (1 byte)
3. Hash de transacción de la entrada que se canjea
4. Índice de la salida que se canjea (4 bytes)
5. ScriptPubKey de la salida que se canjea antepuesto con la longitud del script
6.Número de secuencia (4 bytes)
7.Número de salidas que firmamos (1 byte)
8.Valor total de la salida (8 bytes)
9.ScriptSig para la salida antepuesta con la longitud
10.locktime campo (4 bytes)
11. tipo de código hash (4 bytes)

Entonces, si hago hash de estos datos en formato de bytes dos veces usando el algoritmo SHA256, ¿pasaría mi verificación de firma? Estoy tratando de implementar esto usando Java y este es mi código:

public static boolean verifyUsingSecp256k1(byte[] pub, byte[] dataForSigning,
    BigInteger[] rs) throws Exception {
ECDSASigner signer = new ECDSASigner();
X9ECParameters params = SECNamedCurves.getByName("secp256k1");
ECDomainParameters ecParams = new ECDomainParameters(params.getCurve(),
        params.getG(), params.getN(), params.getH());
ECPublicKeyParameters pubKeyParams = new ECPublicKeyParameters(ecParams
        .getCurve().decodePoint(pub), ecParams);
signer.init(false, pubKeyParams);

return signer.verifySignature(dataForSigning, rs[0].abs(), rs[1].abs());}

Sin embargo, cuando intento verificar mi firma, vuelve como falso. ¿Me estoy perdiendo algo aquí?

Lea esta respuesta primero. Para la verificación, debe realizar los mismos primeros 14 pasos.
@CodingEnthusiast Quiero la respuesta más sobre Verificar una transacción en lugar de firmar una transacción. Con los primeros 14 pasos, probé todo, pero parece que no funciona.
¿Podría publicar la matriz de bytes (paso 13) antes de hacer hash en el paso 14? Por lo general, es fácil pasar por alto el endianness, el CompactInttamaño SignatureScriptdespués de reemplazarlo con PubkeyScript, ... En cuanto a la verificación, debe verificar el código que está usando, No estoy seguro de qué biblioteca es esa .
@CodingEnthusiast Here is my byte array - 0200000001ce8310077e52959fc1046478629a1d7e522ba8445ff780d0229367ee48ac8146000000001976a9141c156160c943f58b30c1ff2be1cc225485f903bd88acffffffff01808900610d0000001976a914505ec67e233a71908713c500487307c59a6c5c1f88ac0000000081000000 I am using the Sighash type as - ALLL|ANYONE_CAN_PAY hence 81 at the end. Espero que no sea un problema sobre cómo capturamos los datos del mensaje.
No veo ningún problema con estos bytes, y su hash (dataForSigning) debería ser el doble de SHA256 de esto, lo que significac3b0386c0d990ab628ac505e8fb612f67d052c5f3cd0ac517854c2efc24ab3e7
@CodingEnthusiast ¡Estoy usando la biblioteca Bouncy Castle para el procedimiento de verificación! ¡Así que tengo que pasar los datos del mensaje hash SHA-256 doble a la función anterior!

Respuestas (1)

Sin embargo, todos los pasos anteriores son correctos. El único inconveniente aquí es que, a excepción de los scripts, todo lo demás se captura en el formato Little Endian (por las razones que sean). Entonces, a excepción del Paso 5 y el Paso 9, todos los demás datos se almacenan en el formato Little Endian. ¡Me tomó un tiempo llegar a esta respuesta! ¡Solo un pequeño consejo para tener en cuenta al implementar!