Ответ 1
Без ключевого слова памяти Solidity пытается объявить переменные в хранилище.
Lead Solidity dev chriseth: "Вы можете думать о хранилище как о большом массиве, который имеет виртуальную структуру... структуру, которую вы не можете изменить во время выполнения - она определяется переменными состояния в вашем контракте".
Таким образом, структура хранилища устанавливается на камне во время создания контракта на основе ваших объявлений переменных уровня контракта и не может быть изменена будущими вызовами метода. НО - содержимое этого хранилища можно изменить с помощью вызовов sendTransaction. Такие вызовы меняют "состояние", поэтому переменные уровня контракта называются "переменными состояния". Таким образом, переменная uint8 storagevar; объявленный на уровне контракта, может быть изменен на любое допустимое значение uint8 (0-255), но этот "слот" для значения типа uint8 всегда будет там.
Если вы объявляете переменные в функциях без ключевого слова memory, тогда твердость попытается использовать структуру хранения, которая в настоящее время компилируется, но может привести к неожиданным результатам. память говорит о прочности, чтобы создать кусок пространства для переменной во время выполнения метода, гарантируя его размер и структуру для будущего использования в этом методе.
память не может использоваться на уровне контракта. Только в методах.
См. запись "Что такое ключевое слово памяти? Что она делает?" в FAQ. Я цитирую его здесь:
Виртуальная машина Ethereum имеет три области, где можно хранить элементы.
Во-первых, это "хранилище", где находятся все переменные состояния контракта. Каждый контракт имеет собственное хранилище, и он постоянно работает между вызовами функций и довольно дорог в использовании.
Вторая - "память", она используется для хранения временных значений. Он стирается между (внешними) вызовами функций и дешевле в использовании.
Третий - это стек, который используется для хранения небольших локальных переменных. Он почти свободен в использовании, но может содержать только ограниченное количество значений.
Для почти всех типов вы не можете указать, где они должны быть сохранены, поскольку они копируются каждый раз, когда они используются.
Типы, в которых так называемое место хранения важны, - это структуры и массивы. Если вы, например, передавать такие переменные в вызовы функций, их данные не копируются, если они могут оставаться в памяти или оставаться в памяти. Это означает, что вы можете изменить свой контент в вызываемой функции, и эти изменения все равно будут видны в вызывающем абоненте.
По умолчанию для места хранения имеются значения по умолчанию, в зависимости от того, к какой переменной относится:
- переменные состояния всегда находятся в хранилище
- аргументы функции всегда находятся в памяти
- локальные переменные хранилища ссылок типа struct, array или mapping по умолчанию
- локальные переменные типа значения (т.е. ни массив, ни структура, ни отображение) не хранятся в стеке