Dies ist mein erster Vertrag überhaupt (aufbauend auf einem eigenen Beispiel-Lernfall, den ich mir ausgedacht habe).
Angesichts dieses Vertrages (vereinfacht):
unit gEval = 0;
contract Group {
struct Grp {
string name;
uint orgId;
Contrib[] contribs;
}
struct Contrib {
uint id;
uint grpId;
Evals[] evals;
}
struct Eval {
uint id;
address evaluator;
uint result;
}
function evalContrib(Contrib c, uint res) public {
require(msg.sender != c.contributor);
Eval eval = Eval(gEval++,msg.sender, res);
c.evals.push(eval);
}
}
Ich bekomme :
Fehler: Member „push“ ist in struct Group.Eval memory[] memory außerhalb des Speichers nicht verfügbar. c.evals.push(eval); ^----------------^
Folgendes verstehe ich: Der Contrib c
Param in der evalContrib
Funktion ist ein Speicherparameter, da es sich um einen Funktionsparameter handelt, während ich versuche, das aufzurufen, c.evals.push(eval)
was storage
ich denke.
Ich habe mehrere Kombinationen von Zuweisungen storage
oder memory
Zeigern ausprobiert, konnte dies jedoch nicht lösen.
Wie kann ich so etwas umsetzen? Kann ich vielleicht nur eine Referenz nach Id bekommen, zB contribs[id].evals.push(eval)
?
Hinweis: Mein Design ist möglicherweise völlig ineffizient für die Solidität (viele Strukturen mit Arrays), daher freue ich mich über jeden Vorschlag.
Sie sollten auf jeden Fall Rob Hitchens Empfehlung folgen.
Nun, um die Warnung zu beheben, sind ein paar Dinge zu beachten:
Wenn die Funktion nicht von außerhalb des Vertrags verwendet werden soll, können Sie sie als intern deklarieren, sodass Sie Strukturen übergeben können
Struct werden als Speicherreferenzen übergeben, aber Sie können den Speicherort mit Arbeitsspeicher oder Speicherung angeben.
function evalContrib(Contrib storage c, uint res) internal {
require(msg.sender != c.contributor);
Eval memory eval = Eval(gEval++, msg.sender, res);
c.evals.push(eval);
}
Rob Hitchens
transient_loop