Почему Solidity просит меня ограничить просмотр функции модификатора состояния?

Версия 0.8.7

Solidity жалуется, что некоторые функции модификатора состояния могут быть ограничены для просмотра, например:

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

По сути, любая функция, изменяющая структуру, имеет предупреждение «изменяемость состояния функции может быть ограничена просмотром».

Ответы (1)

В документации модификатора вида указано, что:

Функции могут быть объявлены как представления, и в этом случае они обещают не изменять состояние.

Кроме того, правила назначения между состояниями хранения и памяти:

Назначения между хранилищем и памятью (или из данных вызова) всегда создают независимую копию.

Так :

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;
}

Вы читали состояние при доступе dummyStructArray[dummyParam], но вы изменяете только копию памяти, а не переменную состояния. Следовательно, ваша функция соответствует требованиям представления, поскольку она не изменяет состояние.

Предупреждение function state mutability can be restricted to viewсовершенно справедливо.

Такое же поведение можно увидеть на этом коде, вы можете попробовать его на Remix :

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

contract Example {
    uint256 public stateVariable = 0;

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

РЕДАКТИРОВАТЬ : Добавление простого примера в соответствии с комментарием ОП.

// 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;
    }
}
Итак, в какой-то момент он обновит исходную структуру, верно?
Нет. Вы обновляете независимую копию только с помощью этого кода. Вам нужно либо напрямую изменить переменную состояния, либо назначить ей свою копию памяти после того, как ваши изменения будут выполнены.
Не могли бы вы уточнить (или какую-нибудь ссылку на код, ссылку и т. д.) о назначении модификаций копии памяти оригиналу?
Я добавил пример, показывающий 3 способа сделать это. Копия памяти / ссылка на локальное хранилище / На месте.
Да теперь понятно, спасибо большое