почему не требуется никакого газа при создании функции публичного просмотра, но при этом сохраняется запись в хранилище?

У меня четыре вопроса. Я надеюсь, что вы можете мне помочь. Хорошие вопросы идеи, может быть, это поможет другим. Заранее спасибо.

Вопрос 1) Я знаю, что если вы ничего не записываете в хранилище, то эта функция свободна от газа. верно? я могу даже сделать функцию публичного просмотра и сделать тысячный цикл for, но поскольку нет причин распространять это изменение на другие узлы, он должен быть бесплатным, даже если цикл for большой, и даже несмотря на то, что я создаю новые переменные в памяти в этой функции. Моя идея верна?

Вопрос 2) Я сделал функцию публичного просмотра, но в этой функции я написал что-то вроде записи числа в массив, а затем, после его записи, я вернул новый добавленный элемент из этого массива. Я трогал хранилище, я записал его туда. но из-за того, что я назвал свою функцию «представление», она не попросила меня поставить газ в метамаске. метамаска вообще не понадобилась, хоть я и писал в хранилище. почему? Мое мнение таково, что это работает для меня, но не для других, и это не будет распространяться по узлам.

Вопрос 3) Все говорят, что нельзя возвращать динамические массивы из функций. Возьмем массив uint[]. Это динамично, но я все еще могу вернуть его. тогда что люди имеют в виду? Я знаю, что не могу вернуть многомерный массив и структуры массива. но я могу вернуть uint[].

Вопрос 4) Я знаю, что если в хранилище есть какие-то данные, например uint[] x. теперь, если я напишу в функции что-то вроде этого: эти uint[] memory mytest = x;данные x, которые были в хранилище, копируются в память. Я прав? Если не? почему? если да, то работает ли наоборот? скопировать из памяти в память? Но я так не думаю, потому что вы не можете ничего записать в хранилище позже, если вы не укажете во время выполнения.

Ответы (1)

  1. Да.
  2. Когда вы вызываете viewфункцию, eth_callвместо eth_sendTransaction. Вызов выполняется локально, и любые изменения состояния отбрасываются. Таким образом, любые записи в хранилище, которые вы сделали, просто не сохраняются.
  3. «Все говорят, что вы не можете возвращать динамические массивы из функций». Тогда "все" ошибаются. Возможно, если бы вы привели источник, кто-нибудь помог бы вам разобраться, что имелось в виду.
  4. Да, копирует из хранилища в память. Да, другой способ тоже работает:

    pragma solidity ^0.4.24;
    
    contract Test {
        uint256[] public foo;
    
        constructor() public {
            uint256[] memory bar = new uint256[](3);
            bar[0] = 1;
            bar[1] = 2;
            bar[2] = 3;
    
            foo = bar;
        }
    }
    
Последний ответ, вы считаете его правильным? Я думаю, что он копирует из памяти в хранилище.
Правильный. Код в моем посте копируется из памяти в хранилище. Вы спросили, скопирован ли код, которым вы поделились, из хранилища в память. Я сказал, что да, бывает. Потом вы спросили, может ли работать наоборот, и я сказал, что да, это тоже работает. Потом я привел пример.
1 неправильно. Не только запись в хранилище требует газа, транзакция, содержащая только цикл, также будет потреблять газ.
@TjadenHess Здесь мы говорим о viewфункциях, выполняемых через eth_call(не транзакцию).
Я не вижу этого в вопросе, хотя это может подразумеваться. viewфункции также могут быть вызваны через транзакции, например, другим контрактом, и в этом случае это все равно будет стоить газа.
Правильно.