Ich versuche, ein Array von Strukturen zu erstellen, die ein Array von Strukturen enthalten.
https://gist.github.com/anonymous/65260d973a5640741a7d6174bf8fe7e6
Aus verschiedenen Suchen geht hervor, dass es nicht möglich ist, eine Struktur mit einem Array von Strukturen zu initialisieren, die auf ein gespeichertes Array geschoben werden sollen, und dass der beste Weg scheint, einfach eine Nicht-Struktur-Array-Variable an einer bestimmten Position im äußeren Array zu setzen .
Leider bekomme ich das anscheinend nicht zum Laufen. Ich habe verschiedene Dinge ausprobiert, aber hauptsächlich um die oben genannten.
Wenn ich laufe truffle test
bekomme ich:
Error: VM Exception while processing transaction: revert
Wenn ich versuche, die createBar-Funktion in der Konsole auszuführen, bekomme ich etwas anderes:
Error: VM Exception while processing transaction: invalid opcode
Ich bin mir nicht sicher, was ich falsch mache. Jeder Lichtschuppen oder Hinweise würden sehr geschätzt werden.
Ein Array hat eine Länge, Sie können nur Elemente zwischen 0 und der Länge des Arrays - 1 verwenden.
Wenn Sie ein neues Element hinzufügen möchten, müssen Sie die Arraygröße erhöhen.
function createBar(uint barNum)
public
returns (uint)
{
uint barId = bars.length;
bars.length += 1;
bars[barId].barNum = barNum;
return barId;
}
Das ist interessant.
Ich bin nicht davon überzeugt, dass diese Art der Verschachtelung für die meisten Fälle ideal ist, da ungeordnete Listen für den wahlfreien Zugriff nicht nützlich sind. Möglicherweise finden Sie zugeordnete Strukturen mit Indizes etwas flexibler.
Gibt es gut gelöste und einfache Speichermuster für Solidity?
Was Sie verlangen, ist praktikabel, also habe ich damit herumgespielt. Keine Garantie. ;-)
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;
}
}
Ich hoffe es hilft.
foobarbaz
Ismael
push
Mitglied zu verwenden, da das manuelle Erhöhen der Länge keine sehr gute Programmiertechnik ist.