ValueError: The private key must be exactly 32 bytes long, instead of 42 bytes.
The problem here is that while the length of a legal private key is indeed 32 bytes, it nevertheless requires 64 ASCII characters from the set [0-9]|[a-f] in order to represent it as a hexadecimal string.
This is because despite the fact that an ASCII character consists of 8 bits, each ASCII character in the set [0-9]|[a-f] actually represents 4 bits when used within a string designated for representing a hexadecimal value.
Let alone, the fact that we also need to prefix that string with two additional characters, namely, "0x".
Hence, in the example above, the illegal private key represents a 20-byte value, using a string of 42 ASCII characters.
There are two possible error messages which would imply the problem in a clear manner:
The private key must be string of exactly 2+64 hexadecimal characters, but 2+40 were provided
The private key must be hexadecimal string which represents exactly 32 bytes, but 20 were provided
Instead, you throw an error-message which is kind of a hybrid of the two options above.
try:
return self._keys.PrivateKey(HexBytes(key))
except ValidationError as original_exception:
raise ValueError(
"The private key must be exactly 32 bytes long, instead of "
f"{len(key)} bytes."
) from original_exception
You probably want to split that up into two try/catch clauses:
First, check if the call to HexBytes succeeds. If not, then the input itself is not a hexadecimal string, and you can throw an error-message which describes that problem in a very accurate manner.
Then, check if the call to PrivateKey succeeds. If not, then the input string represents an incorrect number of bytes, and again - you can throw an error-message which describes that problem in a very accurate manner.
When using a private-key of incorrect length, for example, a private key of 20 bytes instead of 32 bytes:
The following exception is thrown:
The problem here is that while the length of a legal private key is indeed 32 bytes, it nevertheless requires 64 ASCII characters from the set [0-9]|[a-f] in order to represent it as a hexadecimal string.
This is because despite the fact that an ASCII character consists of 8 bits, each ASCII character in the set [0-9]|[a-f] actually represents 4 bits when used within a string designated for representing a hexadecimal value.
Let alone, the fact that we also need to prefix that string with two additional characters, namely,
"0x"
.Hence, in the example above, the illegal private key represents a 20-byte value, using a string of 42 ASCII characters.
There are two possible error messages which would imply the problem in a clear manner:
Instead, you throw an error-message which is kind of a hybrid of the two options above.
The related code is in file account.py, lines 797-803:
You probably want to split that up into two
try
/catch
clauses:HexBytes
succeeds. If not, then the input itself is not a hexadecimal string, and you can throw an error-message which describes that problem in a very accurate manner.PrivateKey
succeeds. If not, then the input string represents an incorrect number of bytes, and again - you can throw an error-message which describes that problem in a very accurate manner.Thanks