Получение идентификатора метода "Keccak hash" в Python

Я пытаюсь получить идентификатор метода, хэш Keccak (SHA-3) в Python, чтобы я мог вызывать функции своих контрактов после их развертывания, как подробно описано в документации ABI: https://github.com/ethereum /wiki/wiki/Эфириум-Контракт-ABI

Это детали, которые 0xcdcd77c0должны быть идентификатором, полученным для функции с подписьюbaz(uint32,bool)

Я попытался воспроизвести это с помощью модуля python sha3 ( 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'

Как я могу получить первые четыре байта из этого в правильном формате для использования в качестве подписи метода в транзакции? Преобразование этого дайджеста в шестнадцатеричный формат, похоже, не дает правильной подписи.

Эфириум использует 256-бит. Если бы sha3 хеш-библиотеки Python был таким же, как Keccak Ethereum, вызов должен был бы выглядеть так: s = hashlib.sha3_256(). Если вы планируете обновить свой пост, чтобы сосредоточиться на неправильной проблеме с библиотекой (а не на неправильном ее использовании одновременно), то s.hexgiest() вашего сообщения'af54f249a9bc75430f5d7fcc6a2154e9f76ac500e4094c7a2167e43ff7fc53f7'

Ответы (1)

В последней (>=1.0) версии pysha3 вы можете воссоздать идентификатор метода с помощью:

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

Если ваша pysha3 старая (например, закреплена на pysha3==0.3), вам нужно:

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

Объяснение: после того, как Ethereum принял то, что на тот момент было самым последним кандидатом на SHA3, стандарт был изменен. То, что использует Ethereum, теперь называется Keccak вместо SHA3.

Спасибо! На моем компе стояла старая версия. Немного неприятно, что это так, я полагаю, что в конечном итоге мне придется реализовать проверку, чтобы увидеть, какую версию использовать.
Да, я думаю, вы могли бы сделать:try: from sha3 import keccak_256 except ImportError: from sha3 import sha3_256 as keccak_256
Что-то в этом роде, просто нужно переработать мой обычный код проверки зависимостей, как мне кажется.
Просто отметим, что при выполнении вышеизложенного я испытал следующее: TypeError: Unicode-objects must be encoded before hashing, решено просто с помощью «baz (uint32, bool)». encode ('utf-8').keccak_256("baz(uint32,bool)".encode('utf-8')).hexdigest()