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.