Просто работая над кодом надежности в последний день, я понял, что помимо сравнения байтов, строк и т. д.
Будет Keccak256
идеальным решением для сравнения больших массивов или больших структур. Потому что, как говорят свойства хеш-функции:
Учитывая x и y с предположением (x != y) => Мы можем предположить, что H(x) != H(y)
Таким образом , сравнение его хэшей заставит нас потратить намного меньше газа, чем повторение массива, и продемонстрирует нам, что они равны или не равны (не имеет значения, по какому индексу).
Итак, на примере:
Предположим, что у нас есть 2 больших массива одного типа. Можно ли будет сделать что-то вроде:
Assert.equal(keccak256(array1)), keccak256(array2));
Это то, что вы делаете, например, для сравнения строк . (Это, если я не ошибаюсь, интерпретируются как массивы в конце).
Чтобы не делать что-то вроде:
Assert.equal(array1[i], array2[i]);
//Implemented on a for loop from i=0 to i=minlength(arr1,arr2)
Очевидно, что другие реализации, такие как добавление сопоставлений или тому подобное, могут довольно хорошо решить проблему, но мне интересно узнать, есть ли какой-нибудь трюк, который позволяет вам сравнивать эти типы структур сkeccak256()
.
Спасибо.
Да, есть!
Так как keccak256
Solidity дает bytes32
значение, вы можете просто сравнить результаты, используя ==
.
Пример:
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)));
}
}
Дэвид Аммуял