Hello I'd like to create a hash using ethersjs that encodes a number of arguments. I previously used ethereumjs-abi's soliditySHA3 function but not sure which of ethersjs crypto utilities is the correct one. It currently looks like this:

const hash = "0x" + abi.soliditySHA3("address", "uint256", "uint256", "address"],[recipient, amount, nonce, contractAddress]).toString("hex");

signature = await web3.eth.personal.sign(hash, from, pwd);

Also, I'd like to know how to make an Ethereum-aware signature using this hash and the sender's address (above). A contract should then be able to decrypt this signature using the same signature, nonce and expected amount. Like so:

 function claimPayment(uint256 amount, uint256 nonce, bytes memory signature) public {
        require(!usedNonces[nonce], "contract already used");
        usedNonces[nonce] = true;

        // this recreates the message that was signed on the client
        bytes32 message = prefixed(keccak256(abi.encodePacked(msg.sender, amount, nonce, this)));
        require(recoverSigner(message, signature) == owner, "signer must be same as owner");


source: Solidity docs


I have found that ethers carries a utility that mimics ethereumjs in the following: ethers.utils.solidityKeccak256.

I also believe the web3 sign can be recreated with the following:

const signingKey = new ethers.utils.SigningKey(connectedWallet.privateKey);
const messageDigest = "0x" + ethers.utils.solidityKeccak256(["address", "uint256", "uint256", "address"],[recepient, amount, nonce, contract.address])
const signature = signingKey.signDigest(messageDigest);

However, I get an error, "Error: invalid hexidecimal string" and still debuggint this.

Your Answer

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

Browse other questions tagged or ask your own question.