¿Puedo crear dinámicamente estructuras de almacenamiento?

Quiero una función que cree un documento en mi contrato. Eliminé todo lo innecesario. Va así:

contract MyContract{
  mapping (uint => document) documents;

  struct document{
      address author;
      bytes32 hashedContent;
  }

  function addDocument(bytes32 docHash) public{
      document newDoc = document (msg.sender,docHash); //*
      [...]
  }
}

Los documentos son estructuras, y quiero crearlos a partir de una función y luego agregarlos permanentemente a una asignación. Tengo un error en la //*línea que dice:

MyContract.document memory is not implicitly convertible to expected type struct MyContract.document storage pointer. document newDoc = document (docHash,msg.sender); ^---------------------------------------------^

(de Remix) La parte izquierda es almacenamiento pero creo que la parte izquierda es memoria.

¿Es posible hacer lo que estoy tratando de hacer?

  • Si es así, ¿qué hice mal?
  • Si no, ¿conoces alguna solución? (Alguien sugirió que hiciera un contrato por separado para cada documento, pero complicaría MUCHO todo teniendo en cuenta el resto de mi contrato y, de preferencia, estoy buscando una solución en un solo contrato .

Respuestas (1)

Puedes hacer esto:

documents[whateverInt] = document(msg.sender,docHash);

Si es absolutamente necesario declarar el documento antes de configurarlo, debe hacer esto:

document memory newDoc = document(msg.sender,docHash);
documents[whateverInt] = (doc);

De lo contrario, newDocserá un puntero de almacenamiento predeterminado, pero document(msg.sender,docHash)será un valor y no un puntero.

¿Empujar estructuras de memoria en un mapeo de almacenamiento lo convierte en almacenamiento?
En cierto sentido. Más precisamente, el documento (msg.sender, docHash) no se trata como un puntero de memoria o un puntero de almacenamiento, es un valor. Si asigna el valor a un puntero de memoria, funciona correctamente, pero si lo asigna a un puntero de almacenamiento, sobrescribirá algo peligrosamente.
Me da el siguiente error:TypeError: Member "push" not found or not visible after argument-dependent lookup in mapping(uint256 => address)
¡Ups! Ver mi edición. Respondí como si estuviera presionando una matriz, sin usar un mapeo.