ethereum / eth-account

Account abstraction library for web3.py
http://eth-account.readthedocs.io/
MIT License
269 stars 156 forks source link

signTypedData_v4 #187

Closed ManuelMaM closed 2 years ago

ManuelMaM commented 2 years ago

I'm trying to get a signTypedData_v4 to use with OpenSea's Seaport contract, I've tried generating it with ethers-js, eth-sign-utils and with eth-accounts but no success yet, i always get my transaction reverted by "wrong signer".

Here is my python code ```py #using eth-account 0.6.1 from eth_account.messages import encode_structured_data from eth_account import Account payload = { "domain": { "name": "Seaport", "version": "1.1", "chainId": 4, "verifyingContract": "0x00000000006c3852cbEf3e08E8dF289169EdE581" }, "message": { "offerer": "0x57B9b7a197fBA298016e0Acd2B4D152A3c2164e7", "zone": "0x00000000E88FE2628EbC5DA81d2b3CeaD633E89e", "orderType": 2, "startTime": 1659352290, "endTime": 1662030690, "salt": 93424063256993908, "offer": [ { "itemType": 2, "token": "0xdfA5E483118d7d30855DF17921af41118B84d214", "identifierOrCriteria": 1184, "startAmount": 1, "endAmount": 1 } ], "consideration": [ { "itemType": 0, "token": "0x0000000000000000000000000000000000000000", "identifierOrCriteria": 0, "startAmount": 950000000000000, "endAmount": 950000000000000, "recipient": "0x57B9b7a197fBA298016e0Acd2B4D152A3c2164e7" }, { "itemType": 0, "token": "0x0000000000000000000000000000000000000000", "identifierOrCriteria": 0, "startAmount": 25000000000000, "endAmount": 25000000000000, "recipient": "0x8De9C5A032463C561423387a9648c5C7BCC5BC90" }, { "itemType": 0, "token": "0x0000000000000000000000000000000000000000", "identifierOrCriteria": 0, "startAmount": 25000000000000, "endAmount": 25000000000000, "recipient": "0xccc37eEef11f226a9C5B6966492cB1c9e746F00F" } ], "zoneHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "totalOriginalConsiderationItems": 3, "conduitKey": "0x0000007b02230091a7ed01230072f7006a004d60a8d4e71d599b8104250f0000", "counter": 0 }, "types": { "EIP712Domain": [ { "name": "name", "type": "string" }, { "name": "version", "type": "string" }, { "name": "chainId", "type": "uint256" }, { "name": "verifyingContract", "type": "address" } ], "OrderComponents": [ { "name": "offerer", "type": "address" }, { "name": "zone", "type": "address" }, { "name": "offer", "type": "OfferItem[]" }, { "name": "consideration", "type": "ConsiderationItem[]" }, { "name": "orderType", "type": "uint8" }, { "name": "startTime", "type": "uint256" }, { "name": "endTime", "type": "uint256" }, { "name": "zoneHash", "type": "bytes32" }, { "name": "salt", "type": "uint256" }, { "name": "conduitKey", "type": "bytes32" }, { "name": "counter", "type": "uint256" } ], "OfferItem": [ { "name": "itemType", "type": "uint8" }, { "name": "token", "type": "address" }, { "name": "identifierOrCriteria", "type": "uint256" }, { "name": "startAmount", "type": "uint256" }, { "name": "endAmount", "type": "uint256" } ], "ConsiderationItem": [ { "name": "itemType", "type": "uint8" }, { "name": "token", "type": "address" }, { "name": "identifierOrCriteria", "type": "uint256" }, { "name": "startAmount", "type": "uint256" }, { "name": "endAmount", "type": "uint256" }, { "name": "recipient", "type": "address" } ] }, "primaryType": "OrderComponents" } payload['message']['zoneHash'] = bytes.fromhex(payload['message']['zoneHash'][2:] payload['message']['conduitKey'] = bytes.fromhex(payload['message']['conduitKey'][2:] payload = encode_structured_data(payload) signed = Account.sign_message(payload,priv_key) ```

This code and using other libs generates: 0x664035976d541c0bedbe55513d6c6f124553e8379a75890750a6560bebc010cc1dd898dfc622d2eb9e0dc3e69742ff8ceed2435dfe1bbf4959a07c1f105e0ebc1b

But when i start the tx with MetaMask it generates : 0x5dbaea0fdf4dac51a0428fbf2d79f9aa66036b33ae461b4626b889911d0a2499647dc1b262fa5a1e50221005e4e9b74f06c37dccb1f1d62cc94a62378d0791011c8d0791011c

Listing in question: https://testnets.opensea.io/assets/rinkeby/0xdfa5e483118d7d30855df17921af41118b84d214/1184

Code using js : https://github.com/ProjectOpenSea/opensea-js/issues/616#issuecomment-1201927237

fselmo commented 2 years ago

Hey @ManuelMaM... thanks for submitting this. We just merged in some very related work that has not yet made it into a release. Kind of coincidental timing as it'll probably be released this week or sometime soon... but can you try again in a virtual environment with the current master branch of eth-account and see if you still have these issues?

ManuelMaM commented 2 years ago

Hello, I was already using the version from the repo 0.6.1

ManuelMaM commented 2 years ago

I'm still getting the same error, I think the error might be on message itself, i dont know how to see the parameters used by metamask to make the sign, but the tx data is the same as mine, but the signature of course

fselmo commented 2 years ago

@ManuelMaM, the version from master is unreleased. It will be 0.7.0 not 0.6.1. To test, you'd have to pip install from the master branch of the repo. See: https://pip.pypa.io/en/stable/topics/vcs-support/

ManuelMaM commented 2 years ago

I did pip3.9 install git+repourl@master, maybe i have same dependency issues

ManuelMaM commented 2 years ago

It is indeed 0.6.1 https://github.com/ethereum/eth-account/blob/master/setup.py#L51

@ManuelMaM, the version from master is unreleased. It will be 0.7.0 not 0.6.1. To test, you'd have to pip install from the master branch of the repo. See: https://pip.pypa.io/en/stable/topics/vcs-support/

fselmo commented 2 years ago

@ManuelMaM, there is no version yet. It will be created depending on the semantic version type. It says 0.6.1 because the version has not been bumped yet, because it is unreleased. However, we have merged things into the master branch since the release of 0.6.1.

This commit is the "end" of the changes that are included in the already-released 0.6.1.

So when you pip install from master it says 0.6.1 but it really has more changes pulled in that will be released eventually but have not yet gone through the release cycle. It is NOT the same as pip installing 0.6.1.

ManuelMaM commented 2 years ago

I see, but i'm indeed using the version from master, i've double checked, but i'm still getting the same error

fselmo commented 2 years ago

I haven't had too much time to look into what's going on here yet but what's strange is I'm fairly certain Metamask uses eth-sig-utils under the hood... so there may be something different in your code that isn't glaringly obvious?

pacrob commented 2 years ago

If you import _hash_eip191_message from eth_account.messages, what does _hash_eip191_message(encode_structured_data(payload)).hex() return?

I get: master code - 7787658b8b91ce59e79165c5e9445c0f8b62efe06877de74e7e524f9a53a8f3e 0.6.1 code - b3f7b84ece8e5a60c294368be00f79e079cb102cf44fe2b7949ad65113972069

ManuelMaM commented 2 years ago

If you import _hash_eip191_message from eth_account.messages, what does _hash_eip191_message(encode_structured_data(payload)).hex() return?

I get: master code - 7787658b8b91ce59e79165c5e9445c0f8b62efe06877de74e7e524f9a53a8f3e 0.6.1 code - b3f7b84ece8e5a60c294368be00f79e079cb102cf44fe2b7949ad65113972069

(venv) [23:45:46] {rebase} maneglegle@manesv:~/Desktop/github.com/opensea-stream/test$ python3.9 signtest.py
7787658b8b91ce59e79165c5e9445c0f8b62efe06877de74e7e524f9a53a8f3e

Same, i believe there is something wrong with the message it self

ManuelMaM commented 2 years ago

I haven't had too much time to look into what's going on here yet but what's strange is I'm fairly certain Metamask uses eth-sig-utils under the hood... so there may be something different in your code that isn't glaringly obvious?

Yeah, i tried eth-sig-utils since metamask tx just works, i think i'll need to debug metamask to see exactly what are they using as the message, since the payload i'm using comes from opensea's API, theoretically it was supposed to be right, and i have painstakingly checked all fields...

sdfgsdfsdf commented 2 years ago

I have the same problem eth-sig-utils is work

pacrob commented 2 years ago

We've written our structured-data hashing/encoding to agree with eth-sig-utils for most use cases, so if both libraries provide the same output, it wouldn't be considered a problem on our end.

If you find something that does look like a problem or have suggestions that would help web3.py work better for your use-case, please open a new issue.