Mensagem de erro
Unexpected recoverable signature length: Expected 65, but got 64 bytes
Também aparece como
- eth_utils.exceptions.ValidationError: Unexpected recoverable signature length: Expected 65, but got 64 bytes
O número de bytes depois de “but got” é o comprimento da sua assinatura. A classe da exceção é `eth_utils.exceptions.ValidationError`.
web3.py / eth-account / eth-keys (Python) — eth_utils.exceptions.ValidationError from Account.recover_message
O que significa
O eth-keys (usado pelo eth-account e pelo web3.py) só monta uma assinatura recuperável a partir de exatamente 65 bytes: r (32), s (32) e o byte de recuperação v. A assinatura que você passou tem outro comprimento — 64 bytes, neste caso —, então a recuperação nem começou. O `w3.eth.account.recover_message` do web3.py lança o mesmo erro, porque delega ao eth-account.
Por que acontece
O v foi armazenado separadamente ou descartado
comumBack-ends que armazenam colunas `r` e `s`, ou front-ends que fatiam a assinatura, perdem o último byte. Sem o v, não é possível recuperar a chave pública de forma inequívoca.
Uma assinatura compacta EIP-2098
ocasionalAssinaturas compactas de 64 bytes embutem o bit de recuperação no bit mais significativo de s. O eth-account não as aceita diretamente.
Texto hex passado como bytes
ocasionalPassar `signature_hex.encode()` resulta em 132 bytes de ASCII em vez de 65 bytes de assinatura. Passe a própria string hex ou `bytes.fromhex(...)` sem o `0x`.
Como corrigir
- 1.
Passar a assinatura completa como a carteira a retorna
`personal_sign` / `eth_signTypedData_v4` retornam uma string hex de 65 bytes; mantenha-a intacta de ponta a ponta.
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.
Expandir assinaturas compactas
Extraia o yParity do bit mais significativo da segunda metade e acrescente v = 27 + yParity.
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])