Tengo un contrato que declara una matriz de estructuras asignadas en storage
.
Desde este contrato, invoco una función en otro contrato, que toma una sola estructura como entrada.
Para solucionar los "obstáculos de sintaxis", paso los contenidos (variables) de la estructura.
Necesitaba agregar algunas variables más a la estructura y ahora aparece el siguiente error de compilación:
Pila demasiado profunda, intente eliminar las variables locales.
Instintivamente creo que la única solución es pasar la estructura a la función "por dirección"
Dado que tengo la matriz de estas estructuras asignadas en storage
, creo que debería ser factible.
Sin embargo, no importa cómo intente escribirlo, sigo recibiendo errores.
Cuando declaro el tipo de retorno como address
, obtengo el siguiente error de compilación:
Tipo de argumento de retorno struct La referencia de almacenamiento de MyStruct no se puede convertir implícitamente a la dirección de tipo esperada.
Cuando declaro el tipo de retorno como MyStruct storage
, obtengo el siguiente error de compilación:
La ubicación debe ser memoria para funciones visibles públicamente (elimine la palabra clave "almacenamiento").
Cuando declaro el tipo de retorno como MyStruct memory
, obtengo el siguiente error de tiempo de ejecución :
Carga de memoria estática de más de 32 bytes solicitada.
¿El estándar Solidity establece en alguna parte que esto no es factible?
Gracias.
Instintivamente creo que la única solución es pasar la estructura a la función "por dirección"
No puede acceder a las direcciones físicas de las variables de almacenamiento (como puede hacerlo con C), esto no está permitido en Solidity. El tipo de dirección solo se usa para hacer referencia a las direcciones de otras cuentas (de contrato o externas), y no se usa para hacer referencia a las direcciones de memoria.
Una solución alternativa sería usar un contrato inteligente para almacenar sus datos en lugar de una estructura. De esta manera, podría pasar la dirección del contrato inteligente en lugar de tener que pasar los datos. He publicado un ejemplo a continuación:
contract Person {
uint public age;
uint public weight;
function Person(uint _age, uint _weight) public {
age = _age;
weight = _weight;
}
}
contract PersonHolder {
address[] public people; // Could use Person[] here
function addPerson(uint age, uint weight) public {
people.push(new Person(age, weight));
}
function getPerson(uint index) public view returns (Person) {
require(people.length > index);
return Person(people[index]);
}
}
struct
con un contract
... Eso es interesante; Lo probaré, gracias!!!struct
, se "creó" implícitamente un constructor para mí. ¿Realmente necesito declararlo explícitamente si cambio a contract
?Person person
, y quiero acceder a age
, entonces necesito usar person.age()
. Esto podría generar algún tipo de impacto en el tiempo de ejecución, que ahora necesito investigar. 2. El compilador me obliga a cambiar el modificador de función de pure
a view
. ¿Alguna idea de por qué?returns (Person)
: ¿devuelve una referencia a ese objeto en la people
matriz, o devuelve una réplica del mismo (que supongo que produciría copiar el objeto original en la pila antes de invocar la función)? Dado que su solución revocó el Stack too deep
error que había recibido anteriormente, creo que el primero es correcto (es decir, el Person
objeto se devuelve por referencia ). ¿Alguna posibilidad de que puedas confirmar esto? ¡¡¡Gracias!!!returns (Person)
, lo que en realidad estoy devolviendo es una dirección en forma de referencia de contrato. También podría hacerlo returns (address)
, pero necesitaría convertir la dirección como una referencia de contrato de Persona para acceder a sus métodos de forma nativa. Encantado de ayudarle :-)Pure functions can only be used when contract state is not read
, pero este es el estado de un contrato diferente (es decir, no el contrato en el que reside la función). ¿Por qué no puede ser la función pure
entonces? ¿No pure
afirma que la función es "pura" sólo con respecto al contrato de "posesión"?Puede que realmente no entienda tu problema. Pero desde mi experiencia y muchas investigaciones en Internet:
Por ejemplo, tengo un contrato que realiza una llamada a otro contrato, algunos tipos de variables no se pueden devolver de esta manera (pero sí con una llamada externa, como una llamada web3js). Esto incluye tipos "profundos", como estructuras.
Nota : esta no es una declaración oficial, solo algunas cosas que obtuve de la experiencia / lectura, si alguien tiene una documentación oficial, haga otra respuesta correcta :)
MyStruct[10][20] private myStructLists
.Stack too deep, try removing local variables
) usando un enfoque diferente. ¿Alguna idea además de lo obvio que se menciona explícitamente en este error?uint256
y realiza llamadas a funciones internas, lo que eventualmente conduce a un uso de la pila por encima del límite permitido.
greg jeanmart
buena vibración
harry wright
buena vibración