Ayuda para usar y leer Arrays[] y asignaciones

Estoy tratando de hacer algo muy simple. Quiero hacer una estructura que contenga los datos de un jugador.

Dentro de esos datos, quiero una matriz para almacenar cosas como su inventario y sus huevos/monstruos actuales.

Sin embargo, no puedo interactuar con las matrices en absoluto, constantemente tengo problemas. ¿Alguien puede decirme qué estoy haciendo mal y por qué no me permite leer y devolver matrices?

contract EtherMon{ 
    uint public starterEgg;
    address public owner;



    struct player{
        uint256 goldAmount;
      uint[10] listOfEggs;
        bool eggCoolDown;
        uint eggTime;
        uint eggID;
        bool battleCoolDown;
        bool breedingCoolDown;
        uint[] ownedEthermon;
    }

      mapping (address => player) public listOfPlayers;

    function EtherMon(){
        owner = msg.sender;

    }

    function createAccount(){


     starterEgg = block.timestamp % 10;

     listOfPlayers[msg.sender].goldAmount  = 100;
     listOfPlayers[msg.sender].listOfEggs[0] = starterEgg;


        }



  function getCurrentEggs() returns (uint[]) {
 uint length =  listOfPlayers[msg.sender].listOfEggs.length;
 uint[] eggArray;
            for(uint i = 0; i < length; i++){
               eggArray[i] =  listOfPlayers[msg.sender].listOfEggs[i];
            }
            return eggArray;
        }

    }

Básicamente solo quiero poder...

  1. Llame a CreateAccount y almacena un uint aleatorio en la matriz que almacena los huevos que tiene un jugador
  2. Saque los datos del huevo del mapeo y véalo/cámbielo

¿Puede alguien darme un ejemplo de una estructura que contenga una matriz (y una asignación porque parece que puedo usar una asignación dentro de una estructura pero tengo problemas con las matrices dinámicas) y tiene funciones de obtención y configuración?

Respuestas (2)

Aquí hay algunos patrones que pueden ayudarte.

pragma solidity ^0.4.15;

contract Storage {

    struct PlayerStruct {
        uint meaningless;
        uint[] dynamicList;
        uint[10] fixedList;
        mapping(bytes32 => uint) keyToUintMap;
    }

    mapping(address => PlayerStruct) public playerStructs;

    function getPlayerDynListLength(address player) public constant returns(uint count) {
        return playerStructs[player].dynamicList.length;
    }

    function appendPlayerDynList(address player, uint value) public returns(uint length) {
        return playerStructs[player].dynamicList.push(value);
    }

    function setPlayerDynFixedList(address player, uint index, uint value) public returns(bool success) {
        require(index <= 9);
        playerStructs[player].fixedList[index] = value;
        return true;
    }

    function getPlayerDynamicListElement(address player, uint index) public constant returns(uint value) {
        return playerStructs[player].dynamicList[index];
    }

    function setPlayerMappedElement(address player, bytes32 key, uint value) public returns(bool success) {
        playerStructs[player].keyToUintMap[key] = value;
        return true;
    }

    function getPlayerMappedElement(address player, bytes32 key) public constant returns(uint value) {
        return playerStructs[player].keyToUintMap[key];
    }

}

Actualizar:

Aquí está en Remix para mostrar que funciona:

ingrese la descripción de la imagen aquí

Espero eso ayude.

¡Gracias Rob! Esto es útil, pero se ve exactamente como lo que estaba tratando de hacer (en cuanto a la sintaxis) y más dividido. Sin embargo, sigo recibiendo el mismo error de Remix IDE: error indefinido: error de VM: código de operación no válido. El constructor debe pagar si envía valor. La ejecución podría haber tirado. Depure la transacción para obtener más información.
Según su descripción, el problema está en la solicitud, no en el contrato. Puede generar el OPCODE no válido de muchas maneras. Posiblemente, el más obvio es caminar desde el final de una matriz. Entonces, si una matriz tiene 2 elementos (0,1) y solicita el índice "2", devolverá un error porque el elemento solicitado no existe.
La imagen está usando el Remix "antiguo" en yann300.github.io , donde puede unirse a los contratos y asegurarse de que sus contratos funcionen como se esperaba. Llamarlos desde JS es otra fuente de problemas potenciales. :-)

Debe modificar su función getCurrentEggs() de esta manera:

function getCurrentEggs() constant returns (uint[]) {
 uint length =  listOfPlayers[msg.sender].listOfEggs.length;
 uint[] memory eggArray = new uint[](length);
            for(uint i = 0; i < length; i++){
               eggArray[i] =  listOfPlayers[msg.sender].listOfEggs[i];
            }
            return eggArray;
        }
 }

1- Dado que la función no modifica ninguna variable de estado, debe marcarse como constante.

2- No está inicializando el eggArray correctamente. Para obtener más información, consulte esta otra pregunta: ¿Cómo inicializar un conjunto vacío e insertar elementos en él?

Actualización: Además, no estoy seguro de por qué está iterando listOfEggs, agregando cada elemento a una nueva matriz y luego devolviendo la matriz mientras podría hacer:

function getCurrentEggs() constant returns (uint[10]) {
    return listOfPlayers[msg.sender].listOfEggs;
    }
De acuerdo. Gracias. ¿En qué se diferencia el almacenamiento de una matriz en la memoria del uso de una matriz dinámica? ¿En términos de costo de almacenamiento? Parece bastante confuso, tenemos arreglos y mapeos, pero cuestan diferente y ahora tenemos arreglos de memoria y arreglos dinámicos. estoy un poco confundido
Traté de devolver listOfPlayer[msg.sender].listOfEggs y dio un error sobre el tipo. Pero su código funciona cuando uso la memoria eggArray.
Estás mezclando conceptos. Le recomiendo que eche un vistazo rápido a los documentos de Solidity. Además, acabo de actualizar mi respuesta ya que hay una forma mucho más simple de hacerlo.