Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

difference of eth_sign and personal_sign #1395

Closed
adamchen0510 opened this issue Jun 16, 2020 · 9 comments
Closed

difference of eth_sign and personal_sign #1395

adamchen0510 opened this issue Jun 16, 2020 · 9 comments

Comments

@adamchen0510
Copy link

https://docs.walletconnect.org/json-rpc-api-methods/ethereum#personal_sign
image
https://docs.walletconnect.org/json-rpc-api-methods/ethereum#eth_sign
image

In the document, there is no difference of eth_sign and personal_sign, but eth_sign may not need add the header '\x19Ethereum Signed Message:\n', would you please help to confirm this?

@pedrouid
Copy link
Member

There is a lot of miscommunication unfortunately about these two going around forums. I've ported this JSON-RPC specification straight from Ethereum EIPs but it fails to clarify the difference

Essentially they have the same digest hashing schema but it happens at different times

eth_sign

This was the original signing method which is now almost completely deprecated. The flow for this method is essentially to hash it before transport. This would result with Wallets receiving a hash that would be unreadable for users to approve

personal_sign

This was introduced later on to solve the readability and essentially differentiates itself by transporting the message without hashing allowing the user to read beforehand. Then after approved the message is hashed accordingly before signed

Comparison

The two flows differentiate as follows:
eth_sign: message -> hash(message) -> JSON-RPC request -> display request -> sign request
personal_sign: message -> JSON-RPC request -> display request -> hash(message) -> sign request

Another difference is the order of the params:
eth_sign: [address, data]
personal_sign: [data, address]
(this resulted because of miscommunication between Geth and Parity development)

Finally we need to take into consideration what the data param refers to:
eth_sign: data = hashed message (32 bytes)
personal_sign: data = hex encoded message (N bytes)

@rmeissner
Copy link
Contributor

I don't think this is correct. If we use eth_sign we never send a hash, we always send the raw data (and get more or less the same data as with personal_sign). Besides the different order the other difference I see is that sometimes personal_sign doesn't adjust v.

@pedrouid
Copy link
Member

Maybe I'm wrong but that's how I understood it given the introduction of the new method was supposedly more secure since it added human readability. @danfinlay would be able to provide more clarity on the above since we wrote the article below

https://medium.com/metamask/the-new-secure-way-to-sign-data-in-your-browser-6af9dd2a1527

@pedrouid
Copy link
Member

pedrouid commented Jul 2, 2020

I found more relevant context on the history of signing on Ethereum on Metamask documentation

https://docs.metamask.io/guide/signing-data.html#a-brief-history

@adamchen0510
Copy link
Author

I found more relevant context on the history of signing on Ethereum on Metamask documentation

https://docs.metamask.io/guide/signing-data.html#a-brief-history

As Metamask described, eth_sign don't add the header but personal_sign add the header, this seems reasonable.

@rmeissner
Copy link
Contributor

rmeissner commented Jan 15, 2021

As Metamask described, eth_sign don't add the header but personal_sign add the header, this seems reasonable.

This is only metamasks implementation, according to the standard it should be different. (see MetaMask/metamask-extension#9957)

Edit:
also in the rpc docs it is nowhere mentioned that eth_sign is deprecated (see https://eth.wiki/json-rpc/API#eth_sign)

@pi0neerpat
Copy link

pi0neerpat commented Feb 16, 2021

I'm attempting to put this to practice. The following line works with MetaMask, but for WC its shows a hex string, rather than the text "Please prove you control this wallet by signing this random text: 792823".

const signature = await walletProvider.getSigner(0).signMessage(message);

Later when calling recoverPersonalSignature from eth-sig-util, the recovered address is incorrect.

I feel as if the behavior here should be the same. There is no signPersonalMessage in ethers (that I've found)

Frontend
"@ethersproject/providers": "^5.0.4"
"@walletconnect/web3-provider": "^1.3.6"

Backend
"eth-sig-util": "^3.0.1"

Frontend code https://github.com/oneclickdapp/ethereum-auth/blob/dc163d31c7e19ae0886f11a85d49a1b9820a85db/src/utils.js#L28

Backend code https://github.com/oneclickdapp/redwood-ethereum-login-demo/blob/2ce1a7bfa1e4a251d36632235280f995a6078b3a/api/src/services/ethereumAuth/ethereumAuth.js#L58

@pedrouid
Copy link
Member

pedrouid commented Dec 9, 2021

This thread is incorrect since it defines an old API (unprefixed eth_sign) as standardized which is not compliant with the latest Ethereum JSON-RPC API

https://github.com/ethereum/execution-apis

UPDATED RESPONSE

eth_sign should ALWAYS be prefixed
personal_sign is only a solution for Metamask

@hackyguru
Copy link

Closing this issue because it is more relevant to discussions.

@chadyj chadyj transferred this issue from WalletConnect/walletconnect-docs Aug 30, 2022
@WalletConnect WalletConnect locked and limited conversation to collaborators Aug 30, 2022
@chadyj chadyj converted this issue into discussion #1396 Aug 30, 2022

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants