Compare estructuras y matrices con keccak256 para ahorrar gasolina

Solo trabajando en un código de solidez el día pasado, descubrí que además de comparar bytes, cadenas, etc.

Keccak256Será la solución perfecta para comparar matrices grandes o estructuras grandes . Porque como dicen las propiedades de las funciones hash:

Dado x e y con la suposición (x != y) => Podemos asumir que H(x) != H(y)

Entonces , comparar sus hashes nos hará gastar mucho menos Gas que iterando la matriz, y nos demostrará que son o no iguales (no importa en qué índice).

Entonces con un ejemplo:

Supongamos que tenemos 2 arreglos grandes del mismo tipo. ¿Será posible hacer algo como:

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

Eso es lo que haces para comparar cadenas, por ejemplo . (Eso si no me equivoco, se interpretan como arrays al final).

Para no hacer algo como:

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

Obviamente, otras implementaciones como agregar mapeos o cosas por el estilo pueden resolver bastante bien el problema, pero me interesa saber si hay algún truco que te permita comparar este tipo de estructuras con elkeccak256() .

Gracias.

Creo que esto debería formularse como una pregunta.

Respuestas (1)

¡Sí hay!

Como keccak256en Solidity arroja un bytes32valor, puede comparar los resultados usando ==.

Un ejemplo:

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)));
    }
}
Una muy buena explicación al demostrar las 2 declaraciones en el mismo código. ¡Muchas gracias y buen trabajo!
No es cierto que hash cualquier valor cueste 30 de gas. Son 30 gases + 6*array.length