1

Ruby ethereum libraries use: https://github.com/phusion/digest-sha3-ruby

require 'digest/sha3'
'0x' + Digest::SHA3.new(256).hexdigest('0x0')
=> "0x77b7d82d931e1a403db0240b08c0716665eec4664af617c457918e4a67bc1810"

... Yet over in javascript land (using both web3 or ethers):

web3.utils.keccak256('0x0')
=> '0xbc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a'

ethers.utils.keccak256('0x0')
=> '0xbc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a'

Why are these outputs different?

UPDATE

It appears the problem is when '0x' is prefixed the js libraries are treating things differently.

> web3.utils.sha3('255')
'0xbebb351b5cf10820d8521e899df75c3dc4c8d740dcf450f315119f5c837945c0'

and in ruby:

'0x' + Digest::SHA3.new(256).hexdigest('255')
=> "0xbebb351b5cf10820d8521e899df75c3dc4c8d740dcf450f315119f5c837945c0"

but then as hex:

> web3.utils.sha3('0xff')
'0x8b1a944cf13a9a1c08facb2c9e98623ef3254d2ddb48113885c3e8e97fec8db9'

and in ruby:

'0x' + Digest::SHA3.new(256).hexdigest('0xff')
=> "0x420daffad4b177bce28bead5f76f7bc97ef63c3aae74c496db8ce6aafe9e6513"
'0x' + Digest::SHA3.new(256).hexdigest('ff')
=> "0x979b141b8bcd3ba17815cd76811f1fca1cabaa9d51f7c00712606970f81d6e37"

...

And then this makes even less sense to me:

> web3.utils.sha3('0x0')
'0xbc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a'
> web3.utils.sha3('0x00')
'0xbc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a'
> web3.utils.sha3('0x000')
'0x54a8c0ab653c15bfb48b47fd011ba2b9617af01cb45cab344acd57c924d56798'
> web3.utils.sha3('0x0000')
'0x54a8c0ab653c15bfb48b47fd011ba2b9617af01cb45cab344acd57c924d56798'
> web3.utils.sha3('0x00000')
'0x99ff0d9125e1fc9531a11262e15aeb2c60509a078c4cc4c64cefdfb06ff68647'
> web3.utils.sha3('0x000000')
'0x99ff0d9125e1fc9531a11262e15aeb2c60509a078c4cc4c64cefdfb06ff68647'

0x0 or 0x00 or 0x0000000000000000000000000000000000000000000000000000000 is all just 0, so why would those result in different digests?

  • A possible difference is that web3.js will accept an hexadecimal string and will convert to a bytes sequence before processing it. Other libraries will not make such conversion. – Ismael Apr 1 at 6:26
1

Turns out the answer is the format of the string being given to ruby's SHA3 implementation:

'0x' + Digest::SHA3.new(256).hexdigest("\xff")

will give the same output as:

web3.utils.sha3('0xff');
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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