Fehlermeldung
Unexpected recoverable signature length: Expected 65, but got 64 bytes
Auch ausgegeben als
- eth_utils.exceptions.ValidationError: Unexpected recoverable signature length: Expected 65, but got 64 bytes
Die Byte-Zahl nach „but got“ ist die Länge deiner Signatur. Die Exception-Klasse ist `eth_utils.exceptions.ValidationError`.
web3.py / eth-account / eth-keys (Python) — eth_utils.exceptions.ValidationError from Account.recover_message
Was der Fehler bedeutet
eth-keys (das von eth-account und web3.py verwendet wird) baut eine wiederherstellbare Signatur nur aus genau 65 Byte: r (32), s (32) und dem Recovery-Byte v. Die übergebene Signatur hat eine andere Länge – in diesem Fall 64 Byte –, daher konnte die Wiederherstellung nicht beginnen. `w3.eth.account.recover_message` von web3.py löst denselben Fehler aus, weil es an eth-account delegiert.
Warum der Fehler auftritt
v wurde separat gespeichert oder verworfen
häufigBackends, die Spalten `r` und `s` speichern, oder Frontends, die die Signatur zerteilen, verlieren das letzte Byte. Ohne v lässt sich der öffentliche Schlüssel nicht eindeutig wiederherstellen.
Eine kompakte Signatur nach EIP-2098
gelegentlichKompakte 64-Byte-Signaturen legen das Recovery-Bit im obersten Bit von s ab. eth-account akzeptiert sie nicht direkt.
Hex-Text als Bytes übergeben
gelegentlichÜbergibst du `signature_hex.encode()`, sind das 132 Byte ASCII statt 65 Byte Signatur. Übergib den Hex-String selbst oder `bytes.fromhex(...)` ohne das `0x`.
So behebst du den Fehler
- 1.
Vollständige Signatur so übergeben, wie die Wallet sie liefert
`personal_sign` / `eth_signTypedData_v4` liefern einen 65-Byte-Hex-String; lass ihn auf dem ganzen Weg unverändert.
python from eth_account import Account from eth_account.messages import encode_defunct # Pass the 0x-prefixed hex string exactly as the wallet returned it (132 hex chars + "0x"). signer = Account.recover_message(encode_defunct(text=message), signature=signature_hex) assert signer.lower() == expected_address.lower() - 2.
Kompakte Signaturen erweitern
Löse yParity aus dem obersten Bit der zweiten Hälfte heraus und hänge v = 27 + yParity an.
python def expand_eip2098(sig: bytes) -> bytes: """64-byte compact signature (r || yParityAndS) -> 65-byte r || s || v.""" r, ys = sig[:32], int.from_bytes(sig[32:], "big") y_parity = ys >> 255 s = ys & ((1 << 255) - 1) return r + s.to_bytes(32, "big") + bytes([27 + y_parity])