11

I tried to use ethers' keccak256 function like this:

import { keccak256 } from "@ethersproject/keccak256";

const signature = keccak256("balanceOf(address)");

But the script failed with this error:

Error: invalid arrayify value (argument="value", value="balanceOf(address)", code=INVALID_ARGUMENT, version=bytes/5.5.0)

How can I make it work?

eth
  • 85,679
  • 53
  • 285
  • 406
Paul Razvan Berg
  • 17,902
  • 6
  • 73
  • 143

2 Answers2

9

With ethers.js v5 you can use:

const { ethers, utils } = require("ethers");

const labelhash = utils.keccak256(utils.toUtf8Bytes("example"))

This is documented here.

Thomas Clowes
  • 4,385
  • 2
  • 19
  • 43
  • 3
    Installing the bespoke @ethersproject/keccak256 package is better when you only need to use the keccak256 function. You avoid installing all the packages that come with the umbrella ethers package. – Paul Razvan Berg Apr 11 '22 at 06:30
8

Let's look at the function definition for keccak256:

export function keccak256(data: BytesLike): string {
    return '0x' + sha3.keccak_256(arrayify(data));
}

The input is not a string - it's a BytesLike type.

With that in mind, here's how to rewrite the script to make it work:

import { keccak256 } from "@ethersproject/keccak256";
import { toUtf8Bytes } from "@ethersproject/strings";

const signature = keccak256(toUtf8Bytes("balanceOf(address)"));

The trick is to import another package from the ethers stack (@ethersproject/strings) that exports a function called toUtf8Bytes, which converts your string to BytesLike.

Paul Razvan Berg
  • 17,902
  • 6
  • 73
  • 143