Puntero de almacenamiento de solidity store en variable de almacenamiento para acceder a él desde distintas funciones

En un contrato, utilizando Solidity, ¿es posible almacenar un puntero a una variable de almacenamiento en una variable de almacenamiento (o en otro lugar que pueda ser adecuado) y acceder a él desde distintas funciones?

Considere el siguiente ejemplo en pseudocódigo de Solidity:

contract AContract {

    struct AStruct { 
      uint a_field;
    }

    AStruct variable_a;
    AStruct variable_b;

    AStruct storage pointer_to_either_a_or_b;

    modifier AModifier()
    {
      if (condition_a)
      {
        pointer_to_either_a_or_b = variable_a;
      }
      else
      {
        pointer_to_either_a_or_b = variable_b;
      }
    }

    function AFunctionUsingPointerToAorB100() internal AModifier()
    {
      pointer_to_either_a_or_b.a_field = 100;          
    }

    function AFunctionUsingPointerToAorB200() internal AModifier()
    {
      pointer_to_either_a_or_b.a_field = 200;          
    }

}

Cada vez que trato de usar la palabra clave "almacenamiento" para una variable de almacenamiento, aparece el siguiente error de compilación para "Astruct storage pointer_to_either_a_or_b":

Error: identificador esperado, se obtuvo 'Almacenamiento'

¿Hay alguna forma de eludir esto, como colocar el puntero en otro lugar del código?

Las variables de estado SIEMPRE son variables de almacenamiento, por lo que no puede agregarlas al almacenamiento de Astruct pointer_to_either_a_or_b; declaración. Ya es una variable de almacenamiento.

Respuestas (1)

Eliminar el almacenamiento de palabras clave en AStruct storage pointer_to_either_a_or_b;resolvería el error (ya que las variables de estado siempre son almacenamiento), pero no podrá lograr lo que está tratando de hacer.

La razón es; dado que AStruct pointer_to_either_a_or_b;es una variable de almacenamiento, asignarle un valor creará una copia independiente, no una referencia a variable_ao variable_b. Se menciona en los documentos de solidez aquí ,

las asignaciones entre almacenamiento y memoria y también a una variable de estado ( incluso de otras variables de estado ) siempre crean una copia independiente.

No sé cuál es su requisito real, pero dependiendo de lo que haya publicado aquí, no usaré un modificador (ni punteros), pero intentaría algo como esto:

function sample(uint _val) public // val = 100 or 200
 {
      if (condition_a)
      {
        variable_a.a_field = _val;
      }
      else
      {
        variable_b.a_field = _val;
      }
}

¡Espero que esto ayude!

FYI: Como sé, las variables locales declaradas dentro de los modificadores no son accesibles dentro de la función.

Gracias por su respuesta. Sospeché que no sería posible acceder a un puntero compartido a una variable de almacenamiento dentro de distintas funciones. El requisito real es tener un conjunto de muchas funciones que seleccionen una variable distinta como salida, dependiendo de una condición dada. Pensé en los modificadores como una opción hipotéticamente buena para crear un puntero a esas variables de salida, pero como dijiste, no es posible acceder a las variables declaradas dentro de los modificadores dentro de las funciones.
Probablemente tendré que usar algo similar a su sugerencia, como esto, usando una función adicional para devolver un puntero: function Greeter_a(uint _val) public // val = 100 or 200 { GetPointer().a_field = _val; } (...) function Greeter_x(uint _val) public // val = 100 o 200 { GetPointer().x_field = _val; } function GetPointer() public return (almacenamiento de tipo variable) { if (condición_a) { return variable_a; } más { devuelve variable_b; } }
Me temo que puede hacer esto getPointer()porque el valor devuelto será una copia de la variable y no apuntará a la variable de estado y la modificará.
Al agregar la palabra clave "almacenamiento" a "devoluciones", en realidad devuelve una referencia a la variable de almacenamiento, como un puntero. Entonces, "devoluciones (almacenamiento de tipo variable)" parece funcionar.