I'm trying to recreate the following Solidity code in python: sha256(x1, y1, x2, y2) where the x's are addresses and the y's are uint256's.
I've installed the correct sha256 library and I can successfully recreate a hash of one argument. But it doesn't work when I try it with multiple arguments, so I think I'm not "tightly packing" the arguments in the same way that Solidity is in sha256().
Here's what I'm trying right now in Python:
x1 = 0x0123456789012345678901234567890123456789
x2 = 0x0123456789012345678901234567890123456789
y1 = 0x0000000000000000000000000000000000000000000000000000000000000001
y2 = 0x0000000000000000000000000000000000000000000000000000000000000001
data = x1[2:] + x2[2:] + y1[2:] + y2[2:]
answer = sha256(data.decode("hex"))
the result is: 0x4e16b1812b95ddb26d9449dff36d48c85c2d0969f6725b117afc83ab2a354968
but an identical function in Solidity gives me: 0x0549a83cb0b851f2025d3600172681973b9944ab1b157e9fae00984061bce198
Any idea what I'm doing wrong?
Best Answer
First, I have to clarify that you stated that the sha3 hash is the result of sha256(x1, y1, x2, y2), but then you tried to calculate sha256(x1, x2, y1, y2). I don't know which of those gave you the result, so I am going to show the solution to both tasks.
Precognition
Cite (https://Solidity.readthedocs.io/en/v0.4.24/units-and-global-variables.html?highlight=abi.encodePacked#abi-encoding-functions):
This note also leads to another realization. Since keccak256(a,b) is equal to keccak256(abi.encodePacked(a, b)), we have to find out how the abi.encodePacked(...) function operates to finally figure out which data was used for your sha256(x1,y1,x2,y2) call.
Cite (https://Solidity.readthedocs.io/en/v0.4.24/abi-spec.html#non-standard-packed-mode):
Solution using Solidity
After implementing the solution in Python, my results were not equal to your given hash. I was looking quite a long time for my error, but I could not find one. So I had to assume, that the hash you provided could actually not belong to the result of sha256(x1,x2,y1,y2) or sha256(x1,y1,x2,y2), which turned out to be the case.
You can execute the following code at https://remix.ethereum.org
Executing the code gives me the following results:
Solution using Python
The existing Python libraries for Ethereum can be found in the package pyethereum (https://github.com/ethereum/pyethereum). They use the package "pycryptodome" (https://pycryptodome.readthedocs.io/en/latest/src/introduction.html) for their keccak256 hash calculations, which I will use in the following example as well.
Python code showing how the get the correct hash for solidities sha256(x1,y1,x2,y2) and sha256(x1,x2,y1,y2) calls:
Output: