0

I am trying to tightly pack some typed data (array of structs or nested JSON) and generate SHA3 hash from it.

In JS, I can use ethereumjs-abi.soliditySHA3() method, ethAbi.soliditySHA3( ['bytes32', 'bytes32'], [ ethAbi.soliditySHA3(new Array(typedData.length).fill('string'), schema), ethAbi.soliditySHA3(types, data) ] );

The above code snippet is how Metamask packed, hashed and eventually signed typed-data. See https://medium.com/metamask/scaling-web3-with-signtypeddata-91d6efc8b290

I want to replicate the logic in smart contract so that I can verify the signature.

In solidity, I tried the following when dealing with an array of 2 elements. Each element has "type", "name" and "value". The schema is a concatenation of "type" and "name".

bytes32 schemaHash = sha3('string', 'string', elem1Schema, elem2Schema); bytes32 dataHash = sha3(type1, type2, elem1Data, elem2Data); bytes32 hash = sha3('bytes32', 'bytes32', schemaHash, dataHash);

The solidity code doesn't generate the same hash as the JS code. I suspect I am not packing the data correctly or using the wrong solidity function.

Yilmaz
  • 1,580
  • 10
  • 24
Thomas
  • 447
  • 3
  • 16
  • Related: https://ethereum.stackexchange.com/questions/2632/how-does-soliditys-sha3-keccak256-hash-uints – eth May 25 '18 at 06:43

1 Answers1

1

I over-think the problem.

The method ethAbi.soliditySHA3([types], [values]) is using the [types] to determine the destination datatypes and perform the necessary paddings / conversion. The [types] are never added to the buffer for sha3 hashing.

And the [types] is not required in solidity because it is a strong typed language. So to achieve the sha3 hashing in solidity, I just need to call sha3(v1, v2, ...). The function will tightly pack the value and then hash the buffer.

Thomas
  • 447
  • 3
  • 16