简体   繁体   中英

unable to verify a signed message in solidity

I am using this tutorial: https://web3py.readthedocs.io/en/stable/web3.eth.account.html#sign-a-message

##  in web3py

sig = Web3.soliditySha3( [uint256, address], [tokens, contractaddress] ) ## used below also
output: HexBytes('0x3efb3cf4e41109f6f1f998401d02dbe894719a8806f45e79a5fab7d4799f00bb')
from eth_account.messages import encode_defunct
msg = sig.hex()
message = encode_defunct(text=msg)
signed_message = w3.eth.account.sign_message(message, private_key=private_key)
signed_message

SignedMessage(messageHash=HexBytes('0x4c0c7077f770069785167e8b7451d63fad1e858ef5251b239eb0781c314000d2'), r=5665764915496639843348851536709769469640799172147461427941649091688603148258, s=48121517563314450138554207713326165180739298862566159641495137088718857193470, v=27, signature=HexBytes('0x0c86b594baa5bb06a0f4054ffdf3896377cfb757d42dcaeacf0241d96a4d5fe26a63d0514338ec600c89ee808dc088e7b3aadc55b9f5d86685d3ff212e2e47fe1b'))

When I pass these params such as signed_message.messageHash and signed_message.signature to the recoversigner(mentioned below) function in the smart contract. It gives the correct address. But when I am passing arguments tokens, contractaddress (used above) to the solidity keccak256(abi.encodePacked(token,address(this))) the message that is genarated is different from the signed_message.messageHash and in turn I get a different address as output from ecrecover .

I checked what is the output of keccak256(abi.encodePacked(..)) . I found It is same as sig value

What I have done:

  1. Make an ERC20 token.

  2. setup the channel

My goal:

  1. sign messages (with web3py)

  2. validate the signed message with solidity.

Like this:

user will pass some arguments: like contract address and number of tokens along with the signed message. and I will validate it with

    function splitSignature(bytes memory sig)
        pure
        internal
        returns (uint8 v, bytes32 r, bytes32 s)
    {
        require(sig.length == 65 , "invalid length");

        assembly {
            r := mload(add(sig, 32))
            s := mload(add(sig, 64))
            v := byte(0, mload(add(sig, 96)))
        }
        if (v < 27) {
            v += 27;
        }

        require(v == 27 || v == 28 , "value of v ");
        return (v, r, s);
    }

    function recoverSigner(bytes32 message, bytes memory sig)
        internal 
        pure
        returns (address)
    {
        (uint8 v, bytes32 r, bytes32 s) = splitSignature(sig);
        return ecrecover(message, v, r, s);
    }

bytes32 message = prefixed(keccak256(abi.encodePacked(token,address(this))));

This is not working properly. I am not getting the correct address as output.

Please help..

I'm not entirely clear on what you're trying to do, but an important clarification to make here is that Web3's eth.sign (and its underlying JSON-RPC call eth_sign ) do not sign a simple hash. It adds a prefix string, with a length embedded.

See the eth_sign docs :

The sign method calculates an Ethereum specific signature with: sign(keccak256("\x19Ethereum Signed Message:\n" + len(message) + message))) .

By adding the prefix to the passed message, your client makes sure that you aren't using eth_sign to sign a transaction (presumably, by accident, or due to attack).

Calling recoverHash(sig, ...) is sort of nonsensical. Although the variable is called " sig ", it is just a hash of some data -- it hasn't been signed by anything.


If you are designing a new message signing scheme, I highly recommend using some kind of standard. If you want the simplest possible option, you could use EIP-191 's "Version 0" message.

For that, you can use eth-account's encode_intended_validator() , which would look something like:

from eth_account.messages import encode_intended_validator
message = encode_intended_validator(YOUR_CONTRACT_ADDR, sig)
signed_message = w3.eth.account.sign_message(message, private_key=private_key)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM