q9f / eth.rb

a straightforward library to build, sign, and broadcast ethereum transactions anywhere you can run ruby.
https://q9f.github.io/eth.rb
Apache License 2.0
204 stars 88 forks source link

eth/signature: fix prefix_message for multibyte characters #120

Closed kudohamu closed 2 years ago

kudohamu commented 2 years ago

Hi, thanks for the useful gem!

I encountered a problem when verifying signature signed with web3.js that in some cases could not be verified correctly. So I tried signing messages using web3.js and eth.rb, and noticed that different signatures are generated only if they contain multibyte characters.

Here is an example.

message signature (generated by web3.js) signature (generated by eth.rb)
hello, ethereum! 0x7b84abfdddd62aee9c598b98f74ae17b7b497b5530a92bd8f262ac33bccaed230fce76c74609e1c8c96b1bebe1a62e46477d3327481d8ed674d6c51bb98c689c1b 0x7b84abfdddd62aee9c598b98f74ae17b7b497b5530a92bd8f262ac33bccaed230fce76c74609e1c8c96b1bebe1a62e46477d3327481d8ed674d6c51bb98c689c1b
こんにちは、イーサリアム! 0xdd809dedbf2099c2306bb443ae201e24fc7fd7fd4f0c00a961b5bae0decc74d715b4715cab5010157e6662b8abcad0062eb47b63cce986623d43a884eb9ff2e41c 0xf502a9db634e0b1e5ccbb88ffe934855c5211b072bcf4b5b51084086c804c61b35b8e29780071685673d8bd3fe2df1f9ee5b569ba13f9363afc2833b0f66215a1b

What's happening?

I found a difference in the logic of prefixing with "known messages" in web3.js and eth.rb. In the known message, eth.rb counts the number of characters, but web3.js counts the number of bytes.

Which is correct?

The EIP-191 specification quotes go-ethereum as follows.

"\x19Ethereum Signed Message:\n" + len(message).

len, a built-in function of golang, is designed to "returns the number of bytes" in the case of string. ref: https://pkg.go.dev/builtin@go1.18.3#len

Therefore, I decided that it was a mistake on the eth.rb side and created this PR.

kurotaky commented 2 years ago

Thanks for the PR :) I will review it.

codecov-commenter commented 2 years ago

Codecov Report

Merging #120 (98b8993) into main (bb640c7) will increase coverage by 0.00%. The diff coverage is 100.00%.

@@           Coverage Diff           @@
##             main     #120   +/-   ##
=======================================
  Coverage   99.74%   99.74%           
=======================================
  Files          67       67           
  Lines        3855     3858    +3     
=======================================
+ Hits         3845     3848    +3     
  Misses         10       10           
Impacted Files Coverage Δ
lib/eth/signature.rb 100.00% <100.00%> (ø)
spec/eth/signature_spec.rb 100.00% <100.00%> (ø)

:mega: Codecov can now indicate which changes are the most critical in Pull Requests. Learn more