¿Cómo se calcula el hash de un Tx? ¿Qué campos deben tener doble hash SHA y en qué orden?
Como lo explicó Gavin Andersen en el foro , para calcular el hash de ID del Tx que se usa en Merkle Tree, se necesita aplicar un hash SHA a todo el mensaje de Tx como se define en la página wiki de Especificación de protocolo dos veces.
Por ejemplo, para el único Tx del Bloque Génesis, se duplicaría la siguiente matriz de bytes:
01000000010000000000000000000000000000000000000000000000000000000000000000FFFFFFFF4D04FFFF001D0104455468652054696D65732030332F4A616E2F32303039204368616E63656C6C6F72206F6E206272696E6B206F66207365636F6E64206261696C6F757420666F722062616E6B73FFFFFFFF0100F2052A01000000434104678AFDB0FE5548271967F1A67130B7105CD6A828E03909A67962E0EA1F61DEB649F6BC3F4CEF38C4F35504E51EC112DE5C384DF7BA0B8D578A4C702B6BF11D5FAC00000000
Y si el hash doble es correcto, daría el siguiente hash:
4A5E1E4BAAB89F3A32518A88C31BC87F618F76673E2CC77AB2127B7AFDEDA33B
3b a3 ed fd 7a 7b 12 b2 7a c7 2c 3e 67 76 8f 61 7f c8 1b c3 88 8a 51 32 3a 9f b8 aa 4b 1e 5e 4a
, pero querrá invertir eso: 4a 5e 1e 4b aa b8 9f 3a 32 51 8a 88 c3 1b c8 7f 61 8f 76 67 3e 2c c7 7a b2 12 7b 7a fd ed a3 3b
, lo que da como resultado el hash real que se usa realmente .function getTransactionHash($transaction_in_hex) { $bin = hex2bin($transaction_in_hex); $hash = hex2bin(hash('sha256', hex2bin(hash('sha256', $bin)))); return bin2hex(strrev($hash)); }
Aquí hay una implementación de python para encontrar el hash doubleSHA256 para el bloque de génesis:
01000000010000000000000000000000000000000000000000000000000000000000000000FFFFFFFF4D04FFFF001D0104455468652054696D65732030332F4A616E2F32303039204368616E63656C6C6F72206F6E206272696E6B206F66207365636F6E64206261696C6F757420666F722062616E6B73FFFFFFFF0100F2052A01000000434104678AFDB0FE5548271967F1A67130B7105CD6A828E03909A67962E0EA1F61DEB649F6BC3F4CEF38C4F35504E51EC112DE5C384DF7BA0B8D578A4C702B6BF11D5FAC00000000
import codecs
//switch the endianness of a given string
def revEndian(string):
return ''.join(reversed([string[i:i+2] for i in range(0, len(string), 2)]))
//convert a bytebuffer into a string
def hashStr(bytebuffer):
return str(codecs.encode(bytebuffer, 'hex'))[2:-1]
//find the double sha256 hash for a given hex string
def doubleSha256(hex):
bin = codecs.decode(hex, 'hex')
hash = hashlib.sha256(bin).digest()
hash2 = hashlib.sha256(hash).digest()
return revEndian(hashStr(hash2))
gavinandresen
elpiachu