Tengo un mapeo de estructuras y una variable de contador para realizar un seguimiento de cuántas estructuras se almacenan en el mapeo.
Para el desarrollo front-end, recomendaría consultar cada estructura utilizando el captador mymapping[mystruct_index] generado automáticamente. ¿O es mejor crear una función captadora específica para recorrer las estructuras X y recuperar estructuras en matrices de 50, por ejemplo? Además, si uso la función getter para obtener solo unas pocas filas de la estructura en lugar de la estructura completa, ¿conducirá a una mayor eficiencia que simplemente hacer una consulta para una estructura? ¿Tiene alguna experiencia con respecto a la interacción frontal con contratos inteligentes? ¿Cuál cree que es el mejor diseño para la eficiencia y la viabilidad a largo plazo del contrato inteligente? Atentamente
Actualmente, Solidity no admite la devolución de una asignación o una lista de tamaño variable, por lo que deberá implementar una función getter como describió que toma un índice.
El enfoque que creo que está describiendo es mantener una segunda lista junto a la asignación y usarla para devolver la asignación en fragmentos como el código fuente a continuación.
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;
}
}
Los view
métodos son de solo lectura y no cuestan gasolina, por lo que técnicamente puede llamarlos tantas veces como desee para mostrar valores en su interfaz. Sin embargo, hay algunas razones para no hacerlo. * Seguiría necesitando potencia de CPU en su nodo Ethereum. Si es una lista lo suficientemente grande, su nodo podría considerarlo un ataque DoS y limitarlo o prohibirlo. Si ejecuta su propio nodo, eso es mucho trabajo o créditos de AWS para gastar en operaciones de cadena de bloques. * La asignación no cambiará mucho entre las llamadas a addValue
. Estaría rehaciendo el trabajo de recuperar principalmente los mismos valores cada vez, incluso si realiza algo de almacenamiento en caché en su front-end.
En su lugar, recomendaría usar eventos de Solidity (registros de EVM), una función que le permite emitir un evento, que se recupera mediante una base de datos que permite que la indexación de un solo paso se lea varias veces fuera de la cadena, como Subgraph https:// thegraph .com/
Esto le permite mantener su código de solidez mínimo y limpio, sin gastar gasolina en un contrato complicado solo para admitir la funcionalidad de front-end que puede descargar fácilmente en sistemas diseñados para ello (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);
}
}
Espero que esto ayude.
kevin wad
kevin wad
Pablo Pham
uint256 _value
devolvería su tipo de estructura.kevin wad
Pablo Pham