Как решить «Структура, содержащая (вложенное) сопоставление, не может быть построена» в Solidity
18 марта 2022 г.Эта ошибка компиляции возникает при попытке создать экземпляр структуры, которая содержит сопоставление в качестве атрибута. Мне нужна была эта структура данных, чтобы написать [этот контракт] (https://github.com/ndehouche/DecentralizedClinicalTrials/blob/main/README.md), чтобы позволить пациентам лицензировать наборы данных, полученные в результате их клинических испытаний, как часть Алговера грант.
Этот тип структуры данных «один ко многим» может быть полезен, например, для кодирования рынка ограниченных по времени лицензий на некоторый контент. В дополнение к содержимому, подлежащему лицензированию, структура должна будет сопоставлять адреса лицензиатов с отметкой времени начала действия их лицензии, чтобы можно было контролировать их доступ.
содержимое структуры{
адрес кредитора;
хэш bytes32;
сопоставление (адрес => uint) лицензий;
Визуально это будет выглядеть так:
Ошибка «Структура, содержащая (вложенное) сопоставление, не может быть построена» появлялась при попытке создать экземпляр структуры обычным способом с последней версией компилятора.
Вот так, например:
функция submitContent(bytes32 _hash) public payable return(uint _id) {
_id=contents[msg.sender].length;
contents[msg.sender].push(content({
владелец: подлежащий оплате (msg.sender),
хэш:_хэш возврата (_id);
Действительно, начиная с версии 0.7.0, структуры или массивы, которые содержат отображение, могут использоваться только в хранилище, поэтому Solidity жалуется, потому что переменные в функции инстанцирования по умолчанию будут находиться в памяти. Вы можете прочитать об этом изменении в документации Solidity.
Соответствующая часть находится в разделе «Удаление неиспользуемых или небезопасных функций»:
Я хотел написать эту короткую заметку, потому что некоторые лучшие результаты при поиске этой ошибки в Google либо устарели, либо доходят до степени «просто не используйте сопоставление в структуре, братан».
Однако этот тип структуры не может быть эквивалентно смоделирован с отдельным сопоставлением для лицензий; чтение и письмо потребовали бы гораздо больше вычислений.
Обходной путь довольно прост, нам просто нужно объявить структуру в хранилище, прежде чем мы создадим экземпляр указателя на нее.
Наша функция submitContent() должна выглядеть так:
функция submitContent(bytes32 _hash) public payable return(uint _id) {
_id= содержимое[msg.sender].length;
хранилище содержимого [] c = содержимое [msg.sender];
c.push();
c[_id].owner = подлежащий оплате (msg.sender);
c[_id].hash=_hash;
вернуть _id;
Оригинал