Как сгенерировать sh3_keccak256 для целочисленных значений, генерируемых Solidity?

Я пытаюсь сгенерировать тот же sha3.keccak_256 целочисленных значений в Python, который генерируется Solidity.

Вот что делает Solidity:

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);
    }
}

Сгенерированный этим хеш 0xdf4ccab87521641ffc0a552aea55be3a0c583544dc761541784ec656668f4c5a

Однако в Python3 я не могу сгенерировать то же самое для целочисленных значений. Если я наберу приведение к строке, то я смогу получить какое-то значение, но оно не соответствует значению Solidity:

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

Любая помощь приветствуется.

2 ответа

Решение

Вам нужно построить правильное двоичное представление, которое должно состоять из двух 32-байтовых целых чисел, соединенных вместе. Возможно, есть и другие способы сделать это, но вот метод, который преобразует все в гекс с правильным заполнением, а затем использует binascii.unhexlify преобразовать в последовательность байтов:

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

# output: 'df4ccab87521641ffc0a552aea55be3a0c583544dc761541784ec656668f4c5a'

Решение

Проверьте web3 библиотека python, которая имеет ряд полезных функций *. В этом случае мы можем использовать Web3.soliditySha3(), Вы передаете типы и данные, и он создает хеш для вас, например:

from web3 import Web3

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

assert result == "0xdf4ccab87521641ffc0a552aea55be3a0c583544dc761541784ec656668f4c5a"

Web3 v4 Note

V4 выходит очень скоро. Он перешел с шестнадцатеричных строк на bytes во многих местах, включая эту функцию. Так что если вы устанавливаете с pip install --pre web3 (и я рекомендую это сделать, пока v4 не станет стабильным), есть небольшое изменение к вышесказанному:

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

Другие источники

Ethereum StackExchange - очень активный сайт для вопросов, связанных с Ethereum. Вы можете получить более быстрые ответы и найти больше уже заданных вопросов. Например, подобный вопрос был задан здесь: функции Python и Solidity keccak256 дают разные результаты.

* Отказ от ответственности: я участвую в репо web3.py.

Другие вопросы по тегам