¿Cómo se calculan los hash de transacciones?

Estoy tratando de calcular el hash de las transacciones en bloques de bitcoin, pero no obtengo las respuestas correctas.

Por ejemplo, el bloque de génesis tiene una sola transacción .

Así es como intento calcular su hash...

Las transacciones se codifican como:

  • una 'nVersión' de 32 bits
  • una lista de transacciones de entrada, vin
  • una lista de transacciones de salida, vout
  • un 'nLockTime' de 32 bits

Para la transacción en el bloque génesis, estos son:

  • nVersión:01000000
  • entradas
    • contar:01
    • 1ra entrada:
      • prevout_hash:0000000000000000000000000000000000000000000000000000000000000000
      • prevout_n:ffffffff
      • guionSig: 4d:04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73
      • secuencia: ffffffff
  • salidas
    • contar:01
    • 1ra salida:
      • valor: 00f2052a01000000(hex(50*10^8) es 0000012a05f200, y bitcoin coloca los bytes en orden inverso)
      • scriptPubKey: 43:4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac
  • nTiempo de bloqueo:00000000

Si encadeno todos esos juntos de extremo a extremo, obtengo 204 bytes:01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000

Tomando el hash sha256 de esto da 27362e66e032c731c1c8519f43063fe0e5d070db1c0c3552bb04afa18a31c6bf.

Tomar el hash sha256 de ese hash da 3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a.

Pero el hash de transacción real según blockexplorer.com es 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b.

¿Qué estoy haciendo mal? ¿Cómo puedo obtener el hash de transacción correcto?

Aquí está mi trabajo en Python:

>>> import Crypto.Hash.SHA256 as hash, binascii
>>> tx = '01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000'
>>> len(binascii.unhexlify(tx))
204
>>> hash.new(binascii.unhexlify(tx)).digest().encode('hex_codec')
'27362e66e032c731c1c8519f43063fe0e5d070db1c0c3552bb04afa18a31c6bf'
>>> hash.new(hash.new(binascii.unhexlify(tx)).digest()).digest().encode('hex_codec')
'3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a'

Respuestas (1)

Tomar el hash sha256 de ese hash da

3b a3 ed fd 7a 7b ..............

Pero el hash de transacción real según blockexplorer.com es

.............. 7b 7a fd ed a3 3b

La respuesta que estaba recibiendo era correcta, pero invertida en bytes. Necesito acostumbrarme a Bitcoin usando almacenamiento little-endian.

Encontré la respuesta a mi propia pregunta poco después de hacerla. ¿Debo borrar la pregunta y la respuesta o dejar ambas?
Es una pregunta válida, es una respuesta correcta y usted hizo el trabajo para encontrarla. Le daría unos días para asegurarme de que alguien no publique una respuesta más completa (o increíble) y luego acepte su propia respuesta. Idealmente, no es la forma en que funciona StackExchange, pero es perfectamente válido para la auto-respuesta; créanme, no marcan tendencia en este caso;)
En realidad, se recomienda publicar y compartir su propia respuesta, cuando corresponda. stackoverflow.com/help/auto-respuesta
Me acabas de ahorrar muchas horas de investigación. Estaba enfrentando exactamente el mismo problema. salud