Web3.solidityKeccak(['bool'], [True])

, Python Web3 yields: 0x5fe7f977e71dba2ea1a68e21057beebb9be2ac30c6410aa38d4f3fbe41dcffd2

This matches the output of keccak256(abi.encodePacked(true)) in Solidity. However, I want the output of keccak256(abi.encode(true)) because my contract has to deal with variably-sized data structures.

In Web3 JS, I could get the correct output (0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6) using:

web3.utils.soliditySha3(web3.eth.abi.encodeParameters(['bool'], [true]))

How do I get it from Python Web3?

Of course I don't need the hash of a boolean. This just serves as an example for easy verification that the correct encoding was used.

  • The word However makes your entire question unclear, since the expression before it and the expression after it are identical. – goodvibration Nov 26 '20 at 21:55
  • In Web3 JS, I could get the correct output - correct according to what (i.e., what scenario other than "web3.js" does this output represent)? – goodvibration Nov 26 '20 at 21:57
  • @goodvibration It is the scenario of normal ABI encoding (as opposed to packed ABI encoding). That's also the difference in the Solidity expressions. – UTF-8 Nov 27 '20 at 5:23

I just found out how it can be done: There is a python library for Solidity ABI encoding and we can abuse the fact that compact ABI encoding of bytes is the identity.

The library can be installed with:

pip install eth_abi

Its documentation is found here: https://eth-abi.readthedocs.io/en/latest/

After importing the library via

import eth_abi

, the hash can be computed as follows:

abiEncoded = eth_abi.encode_abi(['bytes', 'bytes32'], [input1, input2])
hash = w3.solidityKeccak(['bytes'], ['0x' + abiEncoded.hex()])

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.