Estoy tratando de crear una matriz de estructuras que contienen una matriz de estructuras.
https://gist.github.com/anonymous/65260d973a5640741a7d6174bf8fe7e6
A partir de varias búsquedas, parece que no es posible inicializar una estructura con una matriz de estructuras para insertarla en una matriz almacenada y que la mejor manera parece simplemente establecer una variable que no sea una matriz de estructura en una determinada posición en la matriz externa .
Desafortunadamente, parece que no puedo hacer que esto funcione. He intentado una variedad de cosas, pero sobre todo alrededor de lo anterior.
Si corro truffle test
me sale:
Error: VM Exception while processing transaction: revert
Si intento ejecutar la función createBar en la consola, obtengo algo ligeramente diferente:
Error: VM Exception while processing transaction: invalid opcode
No estoy seguro de lo que estoy haciendo mal. Cualquier cobertizo de luz o punteros sería muy apreciado.
Una matriz tiene una longitud, solo puede usar elementos entre 0 y la longitud de la matriz - 1.
Si desea agregar un nuevo elemento, debe aumentar el tamaño de la matriz.
function createBar(uint barNum)
public
returns (uint)
{
uint barId = bars.length;
bars.length += 1;
bars[barId].barNum = barNum;
return barId;
}
Esto es interesante.
No estoy convencido de que este tipo de anidamiento sea ideal para la mayoría de los casos porque las listas desordenadas no son útiles para el acceso aleatorio. Es posible que las estructuras asignadas con índices sean un poco más flexibles.
¿Existen patrones de almacenamiento sencillos y bien resueltos para Solidity?
Lo que estás pidiendo es factible, así que jugué con eso. Sin garantía. ;-)
pragma solidity ^0.4.18;
contract ArrayOfStructsContainsArrayOfStructs {
struct InnerStruct {
uint x;
}
struct OuterStruct {
InnerStruct[] innerStructs;
}
// This can't be public because the "free" getter is too complex for the compiler to work out a default
OuterStruct[] outerStructs;
event LogAppendedOuterStruct(address sender, uint outerStructRow);
event LogAppendedInnerStruct(address sender, uint outerStructRow, uint innerStructRow);
event LogSetInnerStructValue(address sender, uint outerStructRow, uint innerStructRow, uint value);
function appendOuterStruct() public returns(uint row) {
LogAppendedOuterStruct(msg.sender, outerStructs.length);
outerStructs.length++;
return outerStructs.length-1;
}
// The outer structs are in an array, so specify the outerStructRow
function appendInnerStruct(uint outerStructRow) public returns(uint row) {
LogAppendedInnerStruct(msg.sender, outerStructRow, outerStructs[outerStructRow].innerStructs.length);
outerStructs[outerStructRow].innerStructs.length++;
return outerStructs[outerStructRow].innerStructs.length-1;
}
function setInnerStructValue(uint outerStructRow, uint innerStructRow, uint value) public returns(bool success) {
outerStructs[outerStructRow].innerStructs[innerStructRow].x = value;
LogSetInnerStructValue(msg.sender, outerStructRow, innerStructRow, value);
return true;
}
function getInnerStructValue(uint outerStructRow, uint innerStructRow) public view returns(uint value) {
return outerStructs[outerStructRow].innerStructs[innerStructRow].x;
}
}
Espero eso ayude.
foobarbaz
ismael
push
miembro, aumentar la longitud manualmente no es una técnica de programación muy buena.