0

In solidity there is the keccak256 function which hashes its arguments. I use the keccak256 to compute and use the result to check if some entries exist in my array.

I want to compute the same value in javascript and check if the entry exists on the blockchain, although the web3.sha gives different value than the keccak256.

How can I compute the same value for the same arguments?

In console I run this:

web3.sha3("test1");

and my contract:

function hashVal(bytes32 val) public returns(bytes32) {
     return keccak256(val);
 }
1
  • 1
    No one's going to be able to debug your code without seeing it.
    – user19510
    Commented Mar 7, 2018 at 19:48

2 Answers 2

2

Try this:

web3.sha3(web3.padRight(web3.fromAscii("test1"), 66), { encoding: 'hex' });

Explanation:

A bytes32 representation of "test1" is 32 bytes long, while "test1" is only 5 bytes long.

web3.fromAscii("test1") converts the string to its hexadecimal representation with a leading "0x": 0x7465737431.

web3.padRight pads the value with zeros on the right-hand side, like the conversion to bytes32 does. 32 bytes is 64 hexadecimal characters, but to take into account the leading "0x", I'm padding to 66 characters. This producets 0x7465737431000000000000000000000000000000000000000000000000000000, which is a bytes32 representation of the string.

Finally, we pass this value to web3.sha3 and specify the { encoding: 'hex' } option so sha3 interprets the value passed in as hexadecimal rather than ASCII.

10
  • Thanks. What about multiple values? keccak256 supports multiple arguments, how can I do the same with web3.sha3?
    – bunjee
    Commented Mar 7, 2018 at 20:15
  • Concatenate, using tightly-packed ABI. See solidity.readthedocs.io/en/v0.4.20/….
    – user19510
    Commented Mar 7, 2018 at 20:22
  • If you're doing a lot of this, consider using soliditySha3 in web3.js or soliditySHA3 on ethereumjs-abi.
    – user19510
    Commented Mar 7, 2018 at 20:24
  • I thought soliditySha3 is the same but in a different web3 version, no?
    – bunjee
    Commented Mar 7, 2018 at 20:25
  • 2
    Using web3 1.0.0-beta: web3.utils.soliditySha3({ type: 'bytes32', value: web3.utils.fromAscii('test1') });
    – user19510
    Commented Mar 7, 2018 at 21:28
1

If your function is declared as view or pure you can call it from javascript without paying gas, and it should return the exact same result that when it is called from inside the contract

function hashVal(string val) public pure returns (bytes32) {
    return keccak256(val);
}

And from javascript

 var result = await contract.methods.hashVal("hello").call();
1
  • This has the added benefit of ensuring that all client can easily compute it the way the contract does it, now and in the future. Commented Sep 29, 2018 at 19:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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