Часть, доставляющая вам неприятности - это строка uint[] results;
. Массивы, объявленные как локальные переменные, по умолчанию ссылаются на storage
память. Из раздела «Что такое ключевое слово в памяти» в Документация по твердости :
Существуют значения по умолчанию для места хранения в зависимости от того, к какому типу переменных это относится:
- переменные состояния всегда находятся в хранилище
- Аргументы функции находятся в памяти по умолчанию
- локальные переменные хранилища ссылок структуры, массива или типа отображения по умолчанию
- локальные переменные типа значения (т. Е. Ни массив, ни структура, ни отображение) не сохраняются в стеке
В результате вы ссылаетесь на первый слот хранения вашего контракта, который, как оказалось, Home[] public homes
. Вот почему вы получаете весь массив обратно.
Чтобы решить проблему, вам нужно использовать массив memory
. Однако у вас есть дополнительная проблема в том, что вы не можете использовать динамические массивы памяти в Solidity. Обходной путь - выбрать ограничение размера результата и объявить массив статически.
Пример (ограничено 10 результатами):
function listHomesByAddress(string _physicalAddress) public view returns(uint[10]) {
uint [10] memory results;
uint j = 0;
for(uint i = 0 ; i<homes.length && j < 10; i++) {
if(keccak256(homes[i].physicalAddress) == keccak256(_physicalAddress) && homes[i].available == true) {
results[j++] = homes[i].id;
}
}
return results;
}