[Ethereum] Getting Method ID “Keccak hash” in Python

contract-developmenthash-algorithmkeccakpythonsha3

I am trying to derive the Method ID, the Keccak (SHA-3) hash, in Python so that I may call the functions of my contracts once they are deployed as detailed in the ABI documentation: https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI

This details that 0xcdcd77c0 should be the ID derived for the function with the signature baz(uint32,bool)

I have tried to replicate this using the python sha3 module (https://pypi.python.org/pypi/pysha3):

>>> import sys
>>> import hashlib
>>> import sha3
>>> s = hashlib.sha3_512()
>>> s.update(b"baz(uint32,bool)")
>>>s.hexdigest()
'f1bb0cbc152d49505684ee7d2a37a860af1820ff8052ed6b32eddd3d82f97e89b24aac5ef334f94474264795cb7672339aecfc2cd2dc1cd0b87adccada2e7bc1'

How can I get the first four bytes from this in the correct format to use as a method signature in a transaction? Converting this digest to hex doesn't seem to give the correct signature.

Best Answer

With a recent (>=1.0) version of pysha3 you can recreate the method ID with:

from sha3 import keccak_256
sha3_hash = keccak_256("baz(uint32,bool)").hexdigest()
method_id = "0x"+sha3_hash[:8]
print method_id

If your pysha3 is old (eg pinned atpysha3==0.3) you need:

from sha3 import sha3_256
sha3_hash = sha3_256("baz(uint32,bool)").hexdigest()
method_id = "0x"+sha3_hash[:8]
print method_id

Explanation: After Ethereum adopted what was then the most recent candidate for SHA3, the standard was changed. What Ethereum uses is now called Keccak instead of SHA3.