¿Por qué la solidez me pide que restrinja la función del modificador de estado para ver?

Versión 0.8.7

Solidity se queja de que varias funciones de modificadores de estado pueden restringirse a la vista, como:

function updateStruct(
    uint256 dummyParam
) public onlyOwner {
    DummyStruct memory dummy = dummyStructArray[dummyParam];
    dummy.something = 1;
}

Básicamente, cualquier función que modifique la estructura tiene la advertencia "la mutabilidad del estado de la función se puede restringir a la vista".

Respuestas (1)

La documentación del modificador de vista establece que:

Las funciones pueden declararse vista en cuyo caso prometen no modificar el estado.

Además, las reglas de asignación entre almacenamiento y memoria establecen:

Las asignaciones entre almacenamiento y memoria (o desde calldata) siempre crean una copia independiente.

Entonces :

function updateStruct(uint256 dummyParam) public onlyOwner {
    // Creates a memory COPY of dummyStructArray[dummyParam]
    DummyStruct memory dummy = dummyStructArray[dummyParam];
    // Modified the memory COPY
    dummy.something = 1;
}

Leyó el estado al acceder dummyStructArray[dummyParam], pero solo modifica una copia de memoria, no la variable de estado. Por lo tanto, su función se ajusta a los requisitos de la vista ya que no modifica el estado.

La function state mutability can be restricted to viewadvertencia es perfectamente válida.

El mismo comportamiento se puede ver en este código, puedes probarlo en Remix :

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

contract Example {
    uint256 public stateVariable = 0;

    function modifiesInMemory() public {
        uint256 memoryCopy = stateVariable;
        memoryCopy = 10;
    }
}

EDITAR : Agregar un ejemplo simple según el comentario de OP.

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;
    
contract Example {
    struct DummyStruct {
        uint256 something;
    }

    DummyStruct[1] public dummyStructArray;


    // Creates a memory copy and operates on it
    // "Assignments between storage and memory (or from calldata) always create an independent copy."
    function modifiesInMemory() public {
        DummyStruct memory memoryCopy = dummyStructArray[0];
        memoryCopy.something = 10;

        // ASSIGN THE MEMORY COPY BACK TO THE STATE VARIABLE
        dummyStructArray[0] = memoryCopy;
    }

    // Creates a local storage reference to the state variable
    // "Assignments from storage to a local storage variable also only assign a reference."
    function modifiedInLocalStorage() public {
         DummyStruct storage localStorageReference = dummyStructArray[0];
         localStorageReference.something = 10;
    }

    // Directly modifies the state variable
    function modifiesInState() public {
        // MODIFIES THE STATE VARIABLE IN PLACE
        dummyStructArray[0].something = 10;
    }
}
Entonces, básicamente, en algún momento, actualizará la estructura original, ¿verdad?
No. Estás actualizando una copia independiente solo con este código. Debe modificar directamente la variable de estado o asignarle su copia de memoria después de realizar las modificaciones.
¿Puede dar más detalles (o alguna referencia de código, enlace, etc.) sobre la asignación de modificaciones en la copia de memoria al original?
Agregué un ejemplo que muestra las 3 formas de hacerlo. Copia de memoria / referencia de almacenamiento local / In situ.
Sí, ahora tiene sentido, muchas gracias.