Wie berechnet man den Hash eines Tx? Welche Felder müssen doppelt SHA-gehasht werden und in welcher Reihenfolge?
Wie von Gavin Andersen im Forum erklärt - um den ID-Hash des Tx zu berechnen, der im Merkle-Baum verwendet wird, muss man die gesamte Tx-Nachricht zweimal SHA-hashen, wie auf der Wiki-Seite Protocol Specification definiert.
Zum Beispiel würde man für den einzigen Tx aus dem Genesis-Block das folgende Array von Bytes doppelt hashen:
01000000010000000000000000000000000000000000000000000000000000000000000000FFFFFFFF4D04FFFF001D0104455468652054696D65732030332F4A616E2F32303039204368616E63656C6C6F72206F6E206272696E6B206F66207365636F6E64206261696C6F757420666F722062616E6B73FFFFFFFF0100F2052A01000000434104678AFDB0FE5548271967F1A67130B7105CD6A828E03909A67962E0EA1F61DEB649F6BC3F4CEF38C4F35504E51EC112DE5C384DF7BA0B8D578A4C702B6BF11D5FAC00000000
Und wenn es korrekt doppelt gehasht wird, würde es den folgenden Hash geben:
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
, aber Sie sollten das umkehren: 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
, was zu dem tatsächlichen Hash führt, der tatsächlich verwendet wird.function getTransactionHash($transaction_in_hex) { $bin = hex2bin($transaction_in_hex); $hash = hex2bin(hash('sha256', hex2bin(hash('sha256', $bin)))); return bin2hex(strrev($hash)); }
Hier ist eine Python-Implementierung, um den doubleSHA256-Hash für den Genesis-Block zu finden:
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
DerPiachu