Всем доброго времени суток, клиент моей компании желает создать онлайн игру с помощью Solidity. В играх есть игры, и в каждой игре есть свои игроки. это можно сравнить с королевской битвой в игре FPS, где в игре одновременно происходят различные королевские битвы с соответствующими участниками. Я попытался использовать массив внутри структуры, чтобы вести учет игр. Тем не менее, я сталкивался с ошибкой за ошибкой, пытаясь сделать это. Любые предложенные рекомендации будут высоко оценены.
Структура:
struct Game {
address[] participants;
uint amountRequired;
uint Duration;
uint id;
bool ended;
uint createdTime;
}
Функция для создания игры:
function CreateGame(uint amountRequired, string memory timeoption) public restricted{
setGameDuration(timeoption);
gameid++;
Game memory newGame = Game({
participants: address[] participants,
amountRequired: amountRequired,
Duration: gametime,
id: gameid,
ended: false,
createdTime: block.timestamp
});
}
Вам нужно инициализировать массив на отдельной строке, а затем передать его в структуру. См. переменную _participants
во фрагменте:
pragma solidity ^0.8;
contract MyContract {
struct Game {
address[] participants;
uint amountRequired;
uint Duration;
uint id;
bool ended;
uint createdTime;
}
// create a storage mapping of value type `Game`
// id => Game
mapping(uint => Game) public games;
function CreateGame(uint amountRequired, string memory timeoption) public {
// dummy values
address[] memory _participants; // empty array by default
uint gametime = 1;
uint gameid = 1;
Game memory newGame = Game({
participants: _participants,
amountRequired: amountRequired,
Duration: gametime,
id: gameid,
ended: false,
createdTime: block.timestamp
});
// store the `memory` value into the `storage` mapping
games[gameid] = newGame;
}
function addParticipant(uint gameId, address participant) public {
require(games[gameId].createdTime > 0, "This game does not exist");
games[gameId].participants.push(participant);
}
}
Если вы хотите установить некоторых участников кода (не переданных из аргумента), работа с динамическим массивом в памяти немного сложнее. См. этот ответ для получения дополнительной информации и примера.
Редактировать: чтобы добавить участников в массив в отдельной функции, вам нужно сначала сохранить Game
в переменной хранения. См. сопоставление games
в моем фрагменте обновления. Затем вы можете .push()
в массив хранения из отдельной функции.
Я также ищу альтернативное решение, которое включает сопоставление идентификатора игры с массивом адресов. отображение (uint => адрес платежа []) публичных участников; а затем участники (Game.id) = новый адрес для оплаты[ ]; участники(Game.id).push(msg.sender).
@Chukwujike Смотрите отредактированный ответ, там есть пример добавления участников в игру из отдельной функции.
Я реализовал ваше решение в коде и продолжал получать сообщение об ошибке: TypeError: Invalid type for arguments in function call. Запрошено недопустимое неявное преобразование из памяти address[] в память address payable[].
@Chukwujike Я не вижу ничего, что потребовало бы payable
в коде ответа, поэтому это сообщение об ошибке не имеет к нему прямого отношения. В любом случае, при использовании transfer()
и функции в Solidity 0.8+ вам необходимо преобразовать msg.sender
(тип address
) в address payable
с помощью payable(msg.sender).transfer(amount);
. См. этот ответ для получения дополнительной информации ... Или также возможно, что вы изменили определение participants
на address payable[]
- тогда вам также необходимо изменить тип аргумента на address payable[]
.
Спасибо, Петр за ответ. Это очень полезно. Я не совсем понимаю, как добавлять игроков в массивы. Я просмотрел указанный пост и больше запутался, чем нет. Игроки могут войти в игру, вызвав функцию. Затем функция сохраняет их адреса, пока игра не закончится.