В чем разница между Memoryи Storage?
Как с точки зрения EVM, так и с точки зрения контрактного проектирования.
Спасибо!
Они аналогичны памяти и жесткому диску компьютера. Контракт может использовать любой объем памяти (конечно, если он может за это заплатить) во время выполнения своего кода, но когда выполнение останавливается, все содержимое памяти стирается, и следующее выполнение начинается заново. С другой стороны, хранилище сохраняется в самой цепочке блоков, поэтому в следующий раз, когда контракт выполняет некоторый код, он получает доступ ко всем данным, которые он ранее хранил в своей области хранения.
Память временна. Хранение постоянное. Например, вы могли бы выполнять промежуточные вычисления, используя память , а затем сохранять результат в хранилище .
Хранилище — это хранилище ключей и значений, где ключи и значения имеют размер 32 байта. Он разреженный (как хеш-таблица), и нет естественной экономии газа за счет двух 32-байтовых значений рядом друг с другом. Сохранение одного из значений в ключе 1, а другого в ключе 1000 стоит столько же газа, как и их хранение в ключах 1 и 2. (По-прежнему возможна экономия газа за счет хранения упаковки, например, установка 2 uint128
значений в одном ключе. , вместо использования 2 ключей.)
Память представляет собой массив байтов . Память начинается с нулевого размера, но может быть расширена 32-байтовыми фрагментами путем простого доступа или сохранения памяти с индексами, превышающими ее текущий размер. Поскольку память непрерывна , она экономит газ, чтобы сохранить ее упакованной и уменьшить ее размер, вместо того, чтобы иметь большие участки нулей. Дешевле иметь массив длиной 2, хранящий 2 значения, чем массив длиной 1000, где значения находятся на концах массива, а в середине все нули.
Вики тонкостей объясняет дополнительные расходы на газ для использования памяти:
Плата за расширение памяти определяется методом вычитания интегралов. В частности, TOTALFEE(SZ) = SZ * 3 + floor(SZ**2 / 512)
это общая плата за расширение памяти до SZ
32-байтовых фрагментов (примечание: учитываются частично заполненные фрагменты, поэтому 33 байта = 2 фрагмента), и если конкретная операция расширяет память с размера x
до y
, дополнительная стоимость газа составляетTOTALFEE(y) - TOTALFEE(x)
Затраты на хранение газа в основном составляют: 20 000 газа, если значение установлено ненулевым с нуля; 5000 газа при записи в существующее хранилище или установке значения в ноль; и возврат газа в размере 15 000 , когда ненулевое значение установлено равным нулю.
РЕДАКТИРОВАТЬ: EIP-2200, завершенный в 2018 году, содержит дополнительные пояснения по стоимости хранения, например, 800 газа для «хранения» того же значения .
uint128[1] memory t; t[0] = 10;
свою функцию, стоимость вызова газа составит 21581. Когда я уберу эти 2 строки из функции (которые будут полностью пустыми), теперь это будет 21394. Разница примерно в 187 единиц газа. Я просто использовал максимум 1-2 слота. Подставляя 2 в формулу, мы получаем 6. Есть идеи?память похожа на оперативную память вашего кода, которая хранит данные в ней до выполнения вашей функции, после завершения выполнения функции она удаляется. С другой стороны , хранилище похоже на базу данных, которая существует в цепочке блоков независимо от выполнения функции. .
дионизиз