Ich habe eine Zuordnung von Strukturen und eine Zählervariable, um zu verfolgen, wie viele Strukturen in der Zuordnung gespeichert sind.
Für die Front-End-Entwicklung würden Sie empfehlen, jede Struktur mit dem automatisch generierten Getter mymapping[mystruct_index] abzufragen. Oder ist es besser, eine bestimmte Getter-Funktion zu erstellen, um X-Strukturen zu durchlaufen und Strukturen beispielsweise in Arrays von 50 abzurufen. Auch wenn ich die Getter-Funktion verwende, um nur wenige Zeilen der Struktur anstelle der gesamten Struktur abzurufen, führt dies zu einer besseren Effizienz, als einfach eine Abfrage für eine Struktur durchzuführen? Haben Sie Erfahrung in Bezug auf die Front-End-Interaktion mit Smart Contracts, was ist Ihrer Meinung nach das beste Design für Effizienz und langfristige Rentabilität des Smart Contract? Mit freundlichen Grüßen
Solidity unterstützt derzeit nicht die Rückgabe einer Zuordnung oder einer Liste mit variabler Größe, daher müssten Sie eine Getter-Funktion implementieren, wie Sie beschrieben haben, die einen Index akzeptiert.
Der Ansatz, den Sie meiner Meinung nach beschreiben, besteht darin, eine zweite Liste neben der Zuordnung zu führen und sie zu verwenden, um die Zuordnung in Blöcken wie dem folgenden Quellcode zurückzugeben.
contract SomeContract {
mapping(address => uint256) public someMapping;
address[] public addresses;
function addValue(address _newAddress, uint256 _newValue) public {
someMapping[_newAddress] = _newValue;
addresses.push(_newAddress);
}
function getAddressCount() public view returns (uint256 _count) {
return addresses.length;
}
function getValueByIndex(uint256 _index) public view returns (uint256 _val) {
return someMapping[addresses[_index]];
}
// Get the values from mapping in chunks of size 10
// This isn't a feasible solution in my opinion
function getValuesChunk(uint256 _index) public view returns (uint256[10] memory _chunk) {
uint256[10] memory vals;
require(_index < 2^256 - 10, 'Index would wrap around unsafely');
for (uint256 i = _index; i < _index+10; i++) {
vals[i] = someMapping[addresses[i]];
}
return vals;
}
}
Die view
Methoden sind schreibgeschützt und kosten kein Gas, sodass Sie sie technisch so oft aufrufen können, wie Sie möchten, um Werte für Ihr Frontend anzuzeigen. Es gibt jedoch einige Gründe, dies nicht zu tun. * Es würde immer noch CPU-Leistung auf Ihrem Ethereum-Knoten verbrauchen. Wenn die Liste groß genug ist, könnte Ihr Knoten dies als DoS-Angriff betrachten und Sie drosseln oder sperren. Wenn Sie Ihren eigenen Knoten betreiben, ist das eine Menge Arbeit oder AWS-Credits, die Sie für Blockchain-Operationen verbrennen müssen. * Die Zuordnung ändert sich zwischen Aufrufen von nicht wesentlich addValue
. Sie würden die Arbeit des Abrufens der meisten gleichen Werte jedes Mal wiederholen, selbst wenn Sie in Ihrem Front-End etwas zwischenspeichern.
Stattdessen würde ich empfehlen, Solidity-Ereignisse (EVM-Protokolle) zu verwenden, eine Einrichtung, mit der Sie ein Ereignis ausgeben können, das von einer Datenbank abgerufen wird, die es ermöglicht, die One-Pass-Indizierung mehrmals außerhalb der Kette zu lesen, wie z. B. Subgraph https:// thegraph .com/
Auf diese Weise können Sie Ihren Solidity-Code minimal und sauber halten und kein Gas für einen komplizierten Vertrag ausgeben, nur um die Front-End-Funktionalität zu unterstützen, die Sie einfach auf Systeme auslagern können, die dafür entwickelt wurden (GraphQL + React + Typescript).
contract SomeContract {
event NewValue (
address _address,
uint256 _value
);
mapping(address => uint256) public someMapping;
function addValue(address _newAddress, uint256 _newValue) public {
someMapping[_newAddress] = _newValue;
emit NewValue(_newAddress, _newValue);
}
}
Hoffe das hilft.
Kevin Wad
Kevin Wad
Paul Pham
uint256 _value
würden Sie Ihren Strukturtyp zurückgeben.Kevin Wad
Paul Pham