У меня есть смарт-контракт, в котором хранится идентификатор файла вместе с его описанием.
struct AllFiles
{
string fileDesc; //Description of a file
uint fileId; //Corresponding file ID
}
Это сопоставляется со значением uint, которое в основном соответствует идентификатору файла здесь, как
сопоставление (uint => AllFiles) public allFiles;
Я хочу вернуть все содержимое этого сопоставления так же, как мы возвращаем весь массив структур в ООП. Есть ли способ сделать это в Solidity? Я где-то давно читал (сейчас не могу найти ресурс), что массивы не могут быть возвращены. Но поскольку это отображение, интересно, возможно ли это.
отображения не являются итерируемыми. см.: документацию по типу сопоставления , но вы можете построить итерацию поверх нее, например: iterable_mapping.sol (что является хорошим источником вдохновения)
ЕСЛИ ваш ключ uint надежно увеличен, вы можете сохранить что-то вроде a filesCount
и использовать его в итерации. что-то вроде (псевдокод):
contract Files {
struct AllFiles{
string fileDesc; //Description of a file
uint fileId; //Corresponding file ID
}
uint filesCount;
mapping (uint =>AllFiles) public allFiles;
function addFile(string _desc) {
uint id = filesCount+1;
allFiles[id] = AllFiles({fileDesc: _desc, fileId: id});
}
function iterate() {
for(uint256 i = 1; i<=filesCount; i++) {
allFiles[i];
}
}
}
Или вы сохраняете массив с идентификаторами и повторяете его аналогичным образом.
надеюсь, это поможет
@bumi говорит несколько полезных вещей о маппингах. Цикл for
выскакивает как антишаблон, потому что он перестанет работать, когда файлов будет слишком много.
Вы можете создать масштабируемое решение, передав итерацию клиентам. Клиенты запрашивают ряды один за другим, поэтому каждый вызов контракта соответствует стоимости газа. Некоторые идеи здесь: Существуют ли хорошо решенные и простые шаблоны хранения для Solidity?
Надеюсь, поможет.