Ich arbeite an der Implementierung einer intelligenten Vertragsanwendung, in der On- und Off-Chain-Berechnungen vorhanden sein werden. Ich muss die Hash-Funktion mehrerer Ganzzahlen mit Python und Solidity berechnen. Aber Solidity und Python liefern jeweils unterschiedliche Ergebnisse, wie unten gezeigt.
Die Ausgabe für (a=1, b=2, c=3) ist: 49776295142305522338649292811956300178326541500117443588869412604416814650524
Die Ausgabe für (a=1, b=2, c=3) ist: 45637690538541992090000098772847886457082422231295691457910964509567538102535
Ich muss verstehen, wie Solidity die Eingabe-Ganzzahlen codiert und an die Hash-Funktion weitergibt. Wie könnte dies in Python geschehen?
Ich würde mir die Web3.py-Bibliothek ansehen, insbesondere die FunktionWeb3.soliditySha3
Dies funktioniert zum Berechnen des benötigten Hashs:
from web3 import Web3
print(int(Web3.soliditySha3(['uint256', 'uint256', 'uint256'], [1 ,2, 3]), 16))
soliditySha3
gibt ein Byte-ähnliches Objekt zurück, also würden Sie Folgendes tun:print(Web3.toInt(Web3.soliditySha3(...)))
Ab v5 der Web3.py-Bibliothek würden Sie Folgendes tun:
from web3 import Web3, EthereumTesterProvider
w3 = Web3(EthereumTesterProvider())
print(w3.toInt(w3.solidityKeccak(['uint256', 'uint256', 'uint256'], [1, 2, 3])))
49776295142305522338649292811956300178326541500117443588869412604416814650524
Das gibt's auch:
print(w3.toInt(w3.keccak(
b'\x00'*31 + b'\x01' +
b'\x00'*31 + b'\x02' +
b'\x00'*31 + b'\x03')))
49776295142305522338649292811956300178326541500117443588869412604416814650524
eth