Compare structs and arrays with keccak256 in order to save gas

Just working on a solidity code last day, I figured out that apart of comparing bytes, strings etc...

The Keccak256 will be the perfect solution for comparing large arrays or big structs. Because as the Hash functions properties say:

Given x and y with the assumption (x != y) => We can assume that H(x) != H(y)

So comparing it's hashes will make us spend a lot less Gas than iterating the array, and demonstrate us that they are or no equal (doesn't matter on which index).

So with an example:

Let's supose that we have 2 large arrays of the same type. Will it be possible to do something as:

Assert.equal(keccak256(array1)), keccak256(array2));

That is what you do in order to compare strings for example. (That if I'm not wrong, are interpreted as arrays at the end).

In order to don't do something like:

Assert.equal(array1[i], array2[i]);
//Implemented on a for loop from i=0 to i=minlength(arr1,arr2)

Obviously, other implementations as adding mappings or stuff like that can solve quite well the problem, but I'm interested on knowing if there's any trick that allows you to compare this types of stuctures with the keccak256().

Thanks.

• I think this should be phrased as a question. Jun 6 '18 at 13:40

Yes there is!

As keccak256 in Solidity yieds a bytes32 value, you could just compare the outcomes using ==.

An example:

pragma solidity 0.4.24;

contract KeccakCompare {
struct Example {
uint256 age;
bytes32 name;
}

Example[] public examples;

function pushExample(uint256 _age, bytes32 _name) external {
examples.push(Example({
age: _age,
name: _name
}));
}

function equals(uint256 _firstIndex, uint256 _secondIndex) external view returns (bool) {
return equals(examples[_firstIndex], examples[_secondIndex]);
}

function equals(Example storage _first, Example storage _second) internal view returns (bool) {
// Just compare the output of hashing all fields packed
return(keccak256(abi.encodePacked(_first.age, _first.name)) == keccak256(abi.encodePacked(_second.age, _second.name)));
}
}
• A very nice explanation by demonstrating the 2 statements on the same code. Thank you so much and good job! May 30 '18 at 16:28
• It's not true that hashing any value costs 30 gas. It's 30 gas + 6*array.length Jun 1 '18 at 5:05