Ich habe eine Funktion, die ein Adress-Array aus einem anderen Vertrag abruft, msg.sender bedingt aus dem Array löscht und dann das neue Array wieder in diesem Vertrag speichert.
Da sich das Array backerList im Speicher befindet, kann ich das nicht tunbackerList.length--;
Aber ich kann backerList nicht als Speicher-Array deklarieren, da das Speicher-Array nicht in ein Speicher-Array konvertiert werden kann.
Ich stecke hier fest, was soll ich tun?
address[] memory backerList = syndicate.getBackerList();
if(syndicate.individualTotalBacking(msg.sender) == 0){
uint index;
for(uint i=0; i<backerList.length; i++){
if (backerList[i] == msg.sender){
index = i;
}
//shifting array
for(uint k=index; k<backerList.length-1; k++){
backerList[k]=backerList[k+1];
}
}
backerList.length--;
syndicate.setBackerList(backerList);
} else {}
backerList.length--;
Hier ist eine Möglichkeit, dies address[] memory backerList
mithilfe der Inline-Assemblierung zu tun:
assembly { mstore(backerList, sub(mload(backerList), 1)) }
Einige wichtige Punkte, an die Sie sich erinnern sollten:
Stellen Sie sicher, dass dieser Assembler-Code niemals ausgeführt wird backerList.length == 0
(erlauben Sie nicht, dass die Array-Länge unterläuft).
Versuchen Sie nicht, dies zu verwenden, um die Größe eines Arrays zu erhöhen (indem Sie es durch ersetzen sub
) add
.
Verwenden Sie es nur für Variablen mit einem Typ wie ...[] memory
(verwenden Sie es beispielsweise nicht für a address[10] memory
oder address
)
Haftungsausschluss: Die Verwendung der Inline-Assemblierung wird normalerweise nicht empfohlen. Verwenden Sie es mit Vorsicht und auf eigene Gefahr :)
...[] memory
.uint8[2**64-1]
. Wenn Sie uint[] memory a = new uint()[10];
den Compiler ausführen, weist er einen Teil dieses Arrays zu, um a
. Der Compiler kann entscheiden , den Speicher direkt danach a
für andere Zwecke zu verwenden ( b
) , da er zu Recht davon ausgeht , dass kein Sprachfeature wachsen kann a
. Wenn Sie zum Vergrößern die Inline-Assemblierung verwenden, a
überschreiben Sie b
. Wenn ein anderer Code in schreibt b
, überschreibt er den erweiterten Teil von a
. Schlechte Zeiten. Es kann „funktionieren“, weil es kein gibt b
, aber es funktioniert nicht , weil Sie alle Sicherheitsgarantien verloren haben.Ja, Sie haben Recht, Sie können die Größe des Speicherarrays nicht explizit reduzieren, es gilt nur für Speicherarrays. Aber Sie können den Löschoperator verwenden, um den Speicher zu löschen, wodurch Ihr Gas gespart wird.
Die Größe des Arrays ändert sich jedoch nicht, sie bleibt gleich. Sie müssen eine zusätzliche Variable erstellen, um die Größe des Arrays zu verfolgen.
Jesus
setBackerList
?Panda-Power
Jesus
setBackerList
einesaddress[] memory
?Panda-Power