2

I am trying to generate the same sha3.keccak_256 of integer values in Python that is generated by Solidity.

Here is what Solidity does:

pragma solidity ^0.4.18;

contract GenerateHash{
    function generateHashVal(int id, int date) pure public returns (bytes32){
        //Using values - (123,1522228250);
        return keccak256(id,date);
    }
}

The hash generated by this is 0xdf4ccab87521641ffc0a552aea55be3a0c583544dc761541784ec656668f4c5a

In Python3 though, I can't generate the same for integer values. If I type cast it to string then I am able to get some value but that does not match that of Solidity:

>>> s=sha3.keccak_256(repr(data).encode('utf-8')).hexdigest()
>>> print(s)
37aafdecdf8b7e9da212361dfbb20d96826ae5cc912ac972f315228c0cdc51c5
>>> print(data)
1231522228250

Any help is appreciated.

Ankit Sinha
  • 33
  • 1
  • 5

2 Answers2

1

You need to build the right binary representation, which should be two 32-byte integers concatenated together. There are probably other ways of doing that, but here's a method that converts everything to hex with the right padding and then uses binascii.unhexlify to convert to a byte sequence:

sha3.keccak_256(binascii.unhexlify('{:064x}{:064x}'.format(123, 1522228250))).hexdigest()

# output: 'df4ccab87521641ffc0a552aea55be3a0c583544dc761541784ec656668f4c5a'
user94559
  • 59,196
  • 6
  • 103
  • 103
0

Solution

Check out the web3 python library, which has a number of helpful functions*. In this case, we can use Web3.soliditySha3(). You pass in the types and data, and it produces the hash for you, like so:

from web3 import Web3

result = Web3.soliditySha3(['uint256', 'uint256'], [123, 1522228250])

assert result == "0xdf4ccab87521641ffc0a552aea55be3a0c583544dc761541784ec656668f4c5a"

Web3 v4 Note

v4 is coming out very soon. It has switched from hex strings to bytes in many places, including this function. So if you install with pip install --pre web3 (and I recommend you do, until v4 goes stable), there is a slight modification to the above:

assert Web3.toHex(result) == "0xdf4ccab87521641ffc0a552aea55be3a0c583544dc761541784ec656668f4c5a"

Other Resources

The Ethereum StackExchange is a very active site for Ethereum-specific questions. You may get faster responses, and find more already-asked questions. For example, a similar question was asked here: Python and Solidity keccak256 function gives different results.

* Disclaimer: I am a contributor to the web3.py repo.

carver
  • 2,229
  • 12
  • 28
  • I am using web3.py only for my project, it just didn't click to check out its library for this task. Thanks for the info. – Ankit Sinha Mar 30 '18 at 01:10