Моя версия solc:
"solc": "^0.7.1",
Когда я пытаюсь создать структуру, содержащую сопоставление, я получаю эту ошибку: «Структура, содержащая (вложенное) сопоставление, не может быть построена»
Это мой код солидности.
Кампания.sol
pragma solidity >=0.5.0;
contract Campaign {
struct Request {
string description;
// I declared a mapping inside of a struct.
mapping(address => bool) approvals;
}
constructor(uint256 minimum, address creator) {
...
}
function createRequest(string memory description) public onlyManager {
Request memory newRequest = Request({
// Here the compiler gives me an error
description : description
});
}
...
Это говорит
Struct containing a (nested) mapping cannot be constructed.
Пожалуйста, помогите мне.
Проблема в конструкции, т.е. Request({ description: description })
поэтому смена расположения newRequest
с memory
на storage
не поможет.
Если вы действительно хотите, чтобы это работало, создайте переменную состояния, скажем, mapping (uint => Request) requests
. Теперь внутри вашей функции вы можете написать, Request storage newRequest = requests[index]
где index
будет увеличиваться позже.
Для справки см.: документы
mapping(address => Request)
approvals
? @hrkrshnnс 0.7.0 сделайте как показано ниже:
struct Request{
string description;
uint value;
address recipient;
bool complete;
uint approvalsCount;
mapping(address => bool) approvals;
}
uint numRequests;
mapping (uint => Request) requests;
function createRequest (string memory description, uint value,
address recipient) public{
Request storage r = requests[numRequests++];
r.description = description;
r.value = value;
r.recipient = recipient;
r.complete = false;
r.approvalsCount = 0;
}
Этого должно быть достаточно:
function createRequest(string memory description) public onlyManager {
Request storage newRequest = requests.push();
newRequest.description = description;
}
Ваше здоровье!
Вы не можете создать сопоставление (или структуру, содержащую сопоставление) в памяти.
Итак, преобразуйте свой код из этого:
contract Campaign {
struct Request {
string description;
uint value;
address recipient;
bool complete;
uint approvalCount;
mapping(address => bool) approvals;
}
Request[] public requests;
function createRequest(string memory description, uint value, address recipient) public restricted {
Request memory newRequest = Request({
description: description,
value: value,
recipient: recipient,
complete: false,
approvalCount: 0
});
requests.push(newRequest);
}
}
к этому
contract Campaign {
struct Request {
string description;
uint value;
address recipient;
bool complete;
uint approvalCount;
mapping(address => bool) approvals;
}
uint numRequests;
mapping (uint => Request) requests;
function createRequest(string memory description, uint value, address recipient) public restricted {
Request storage r = requests[numRequests++];
r.description = description;
r.value = value;
r.recipient = recipient;
r.complete = false;
r.approvalCount = 0;
}
}
Я хочу добавить некоторую справочную информацию, чтобы помочь тем, кто переходит от среды с управляемой памятью (например, .NET CLR) к EVM:
struct
в стеке использует memory
, вот почему это сообщение об ошибке появляется при попытке создать экземпляр Solidity struct
, который содержит mapping
.new
ключевое слово в C#). В Solidity этот шаг абстрагируется от разработчика, вместо этого Solidity EVM автоматически делает это за нас за кулисами. В частности, это происходит при mapping
объявлении переменной. Вот почему в примерах кода на этой странице не показан этап выделения памяти, а вместо этого просто сразу переходите к настройке mapping
значений.Вы не можете создать struct
с отображением внутри. Создайте локалку mapping
в своем контракте на верхнем уровне.
хорошая вибрация
Сан Хун Шин
хорошая вибрация
хорошая вибрация
Сан Хун Шин
хорошая вибрация
Сан Хун Шин
альпер
solidity version 7.0
, когдаpush
использовалось