The main issue in your JavaScript code is related to how data is encoded before hashing. In Solidity, keccak256(abi.encodePacked(address, bytes32))
uses a packed encoding. However, the ethers.utils.defaultAbiCoder.encode
method does not produce a packed encoding; instead, it follows the standard ABI encoding, which includes padding to 32 bytes for each value.
In order to get the same hash as keccak256(abi.encodePacked(address, bytes32))
in Solidity, you need to use a packed encoding. You can use the ethers.utils.solidityPack
function to achieve this. Here’s how to modify your code to generate the correct hash:
const ethers = require('ethers'); // or import ethers if using modules
const types = ["address", "bytes32"];
const values = [myAddress, hash];
// Using solidityPack for packed encoding
const packedData = ethers.utils.solidityPack(types, values);
const correctHash = ethers.utils.keccak256(packedData);
console.log(correctHash);
abi.encode
instead. For reference: ethereum.stackexchange.com/questions/119583/…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 computedabi.encodePacked
is used bydefaultAbiCoder
? You should really only useabi.encodePacked
if you know what you are doing, as it can lead to hash collisions when used with dynamic types (see: discussion). The functionabi.encode
is available in Solidity