0

I want to create a hash in JavaScript for a signature. The hash needs to have the same output as this in solidity:

keccak256(abi.encodePacked(address, bytes32))

My solution in JavaScript so far produces a differing hash:

const types = ["address", "bytes32"];
const values = [myAddress, hash];
const message = ethers.utils.defaultAbiCoder.encode(types, values);
const hash = ethers.utils.keccak256(message);

How can I reproduce the code in Solidity in JavaScript?

rajohs
  • 179
  • 7
  • Have you tried using abi.encode instead. For reference: https://ethereum.stackexchange.com/questions/119583/when-to-use-abi-encode-abi-encodepacked-or-abi-encodewithsignature-in-solidity – Markus Schick Jan 25 '23 at 23:31
  • abi.encode as part of which package? – rajohs Jan 25 '23 at 23:34
  • in solidity the address is 20 byte array, the hash is 32 byte array. In Javascript what is your address? A string with 0x and hexadecimal characters? That would be an error. Same for the hash. You have to handle raw bytes in javascript – Nulik Jan 26 '23 at 00:41
  • encodePacked() is the correct function as 'packed' means that when the variable is smaller than 32 bytes it will be used as its true size is, if it is not packed, then it will be aligned on 32 bytes with prepended 0s and computed – Nulik Jan 26 '23 at 00:43
  • Are you sure that abi.encodePacked is used by defaultAbiCoder? You should really only use abi.encodePacked if you know what you are doing, as it can lead to hash collisions when used with dynamic types (see: discussion). The function abi.encode is available in Solidity – Markus Schick Jan 26 '23 at 09:33

1 Answers1

0

The discussion above explains the problem with my code already. Although in pieces.

I am using abi.encodePacked in my solidity code and ethers.utils.defaultAbiCoder.encode in my JS code.

encodePacked gives additional padding to the input variables to get it to 32 bytes, while encode takes them as is.

TLDR: I have to use the same encoding in JS ans Solidity.

rajohs
  • 179
  • 7