Получение ошибки при попытке сохранить большие полезные нагрузки (13-20 КБ)

Я создал простой смарт-контракт для хранения больших объемов данных (13-20 КБ) в блокчейне Ethereum. Но когда я пытаюсь совершить транзакцию, они иногда терпят неудачу (с небольшой корреляцией с объемом данных) с ошибкой «Предупреждение! Ошибка во время выполнения контракта [Нет газа]».

Лимит газа составляет 3000000, и нет четкого порога данных, который приводит к сбою транзакции. Две транзакции с одинаковым содержимым могут вести себя по-разному (одна выдает ошибку, а другая нет).

Вот код, который я использую для хранения данных:

contract SimpleStorage { 
    mapping(address => string) public Usersdata; 
    function Storedata(string data) public { 
        Usersdata[msg.sender] = data; 
    } 

    function getData() public view returns (string) { 
        return Usersdata[msg.sender]; 
    } 
}
Прежде всего, я очень надеюсь, что вы не собираетесь запускать это в основной сети! Во- вторых, 3 миллионов газа недостаточно для хранения такого количества данных. Как вы храните данные? Вы просто включаете его как данные tx?
Сейчас он работает в тестовой сети, но я планирую запустить его в основной сети в будущем.
Как вы храните данные в сети? Вы просто включаете его как данные tx или помещаете в контрактное хранилище?
Когда транзакции успешны, они используют значительно меньше газа. И да, данные хранятся как данные tx.
Я не могу ответить ни на один вопрос, не видя контракт, с которым вы взаимодействуете.
контракт SimpleStorage { сопоставление (адрес => строка) public Usersdata; function Storedata(string data) public {Usersdata[msg.sender] = data; } функция getData() возвращает публичное представление (строка) { return Usersdata[msg.sender]; } }

Ответы (1)

Основываясь на контракте, который вы прокомментировали (и я отредактировал, чтобы добавить к исходному вопросу), неудивительно, что вы столкнулись с проблемами с газом. Хранилище контракта стоит 20k за инициализацию слота, и каждый слот хранит 32 байта. Хранение 10 КБ данных в хранилище обойдется примерно в 10000/32*20000 газа, что составляет более 6 миллионов газа. Это также игнорирует стоимость данных в качестве входных данных, что недешево (хотя это намного дешевле, чем стоимость хранения). В целом, хранение таких больших наборов данных в сети считается плохой практикой.

Я выполнил транзакцию с полезной нагрузкой 10 КБ и использовал ~ 7000000 газа. Я установил цену на газ в размере 1 gwei. Который стоит всего 0,78 доллара. Будет ли цена такой же, если я разверну ее в основной сети? Знаете ли вы разумный вариант хранения в сети?
Нет дешевого способа хранить столько данных в сети. Просто нереально захотеть добавить столько данных в хранилище. Если вам не нужно работать с данными в рамках вашего контракта, и они предназначены только для хранения, вы можете хранить данные в IPFS и помещать хэш IPFS в цепочку.
@flygoing, скажем, если «Usersdata» уже содержит 1000 записей; EVM должен прочитать все данные в памяти; добавить новую запись и сохранить новую версию. В таком случае; включает ли стоимость только размер новой записи или размер существующих записей?
Убедитесь, что вы не перепутали память и хранилище, это две совершенно разные вещи. EVM не обязательно считывать все данные. В контракте, который вы использовали в качестве примера, вам придется заплатить только за хранение новых данных, ничего больше, но, конечно, это очень дорого.