Использование вложенного массива с твердостью

Всем доброго времени суток, клиент моей компании желает создать онлайн игру с помощью 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

        });
        
    }
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
47
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам нужно инициализировать массив на отдельной строке, а затем передать его в структуру. См. переменную _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() в массив хранения из отдельной функции.

Спасибо, Петр за ответ. Это очень полезно. Я не совсем понимаю, как добавлять игроков в массивы. Я просмотрел указанный пост и больше запутался, чем нет. Игроки могут войти в игру, вызвав функцию. Затем функция сохраняет их адреса, пока игра не закончится.

Chukwujike 18.03.2022 11:04

Я также ищу альтернативное решение, которое включает сопоставление идентификатора игры с массивом адресов. отображение (uint => адрес платежа []) публичных участников; а затем участники (Game.id) = новый адрес для оплаты[ ]; участники(Game.id).push(msg.sender).

Chukwujike 18.03.2022 11:10

@Chukwujike Смотрите отредактированный ответ, там есть пример добавления участников в игру из отдельной функции.

Petr Hejda 18.03.2022 13:49

Я реализовал ваше решение в коде и продолжал получать сообщение об ошибке: TypeError: Invalid type for arguments in function call. Запрошено недопустимое неявное преобразование из памяти address[] в память address payable[].

Chukwujike 19.03.2022 13:22

@Chukwujike Я не вижу ничего, что потребовало бы payable в коде ответа, поэтому это сообщение об ошибке не имеет к нему прямого отношения. В любом случае, при использовании transfer() и функции в Solidity 0.8+ вам необходимо преобразовать msg.sender (тип address) в address payable с помощью payable(msg.sender).transfer(amount);. См. этот ответ для получения дополнительной информации ... Или также возможно, что вы изменили определение participants на address payable[] - тогда вам также необходимо изменить тип аргумента на address payable[].

Petr Hejda 19.03.2022 14:01

Другие вопросы по теме