I am trying to verify a message with Solidity and Python but for some reason the ecrecover is returning an arbitrary address. I have narrowed the problem down to this part here:

messageHashLocal = w3.solidityKeccak(['uint256', 'string', 'uint256'], [amount, message, nonce])
encoded_message = encode_defunct(primitive=messageHashLocal)
signed_messageLocal = w3.eth.account.sign_message(encoded_message, private_key=PRIVATE_KEY)

This is how I get the message hash, encode and sign it.

function getMessageHash(
    uint256 _amount,
    string memory _message,
    uint256 _nonce
) public pure returns (bytes32) {
    return keccak256(abi.encodePacked(_amount, _message, _nonce));

function getEthSignedMessageHash(bytes32 _messageHash)
    returns (bytes32)
        keccak256(abi.encodePacked("\x19Ethereum Signed Message: \n32", _messageHash));

This is how I am generating the message hash and prefixing the "\x19Ethereuem...." string.

Issue: Signed message hash I get back from getEthSignedMessageHash (in Solidity) and the one inside signed_messageLocal (in python) are different and ecrecover is also returning an arbitrary address.

Any ideas what's wrong here? Thanks!


1 Answer 1


I recommend passing your string value to "keccak256" by changing it to "bytes", for example, you can pass " _message" like this : keccak256(bytes( _message))

It will work but if it does not work, try to pass values one by one to find a problem. (it needs to change your smart contract and pythons code)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.