У меня есть предупреждение о проверке ворса в Remix для моего смарт-контракта в Solidity:addFeature(int128,uint256,bool,uint256,uint256,uint16,uint16,address) high: infinite. If the gas requirement of a function is higher than the block gas limit, it cannot be executed. Please avoid loops in your functions or actions that modify large areas of storage (this includes clearing or copying arrays in storage)
Feature
представляет собой структуру с множеством полей:
struct Feature {
int128 key;
uint256 goal;
bool finishOnGoal;
uint campaignStart; // timestamp
uint campaignFinish; // timestamp
PledgeType pledgeType; // enum
FixedPledge fixedPledge; // description for enum value #1
VariablePledge variablePledge; // description for enum value #2
PrepaymentType prepaymentType; // enum
FixedPrepayment fixedPrepayment; // description for enum value #1
PercentPrepayment percentPrepayment; // description for enum value #2
uint16 maxDevelopmentDelay; // days
uint16 developmentDuration; // days
ConfirmationType confirmationType; // enum
UserConfirmation userConfirmation; // description for enum value #1
address developer;
}
...
// featureKey => feature
mapping (int128 => Feature) features;
// featureKey => feature
mapping (int128 => FeatureData) data;
...
// common feature data
function addFeature(
int128 key,
uint256 goal,
bool finishOnGoal,
uint campaignStart, // timestamp
uint campaignFinish, // timestamp
uint16 maxDevelopmentDelay,
uint16 developmentDuration,
address developer) public
ownerOnly
withState(key, State.NotSet)
{
Feature memory feature;
feature.key = key;
feature.goal = goal;
feature.finishOnGoal = finishOnGoal;
feature.campaignStart = campaignStart;
feature.campaignFinish = campaignFinish;
feature.maxDevelopmentDelay = maxDevelopmentDelay;
feature.developmentDuration = developmentDuration;
feature.developer = developer;
FeatureData memory featureData;
featureData.state = State.Deployment;
featureData.backers = new address[](0);
featureData.raised = 0;
featureData.prepaid = 0;
features[key] = feature;
data[key] = featureData;
}
Почему у меня это предупреждение? Что можно/нужно изменить, чтобы это исправить (без потери функциональности)? Насколько я знаю, здесь нет ни циклов, ни модификаций массивов ( только карты ).
Вот минимальный контракт, демонстрирующий проблему:
pragma solidity ^0.4.24;
contract Test {
mapping (uint128 => address[]) data;
function addFeature() public {
data[0] = new address[](0);
}
}
Вы можете убедиться, что это проблема, с которой вы столкнулись, избавившись от поля address[]
и FeatureData
проверив, получаете ли вы по-прежнему оценку бесконечного газа.
Я считаю, что проблема в том, что статический анализ недостаточно сложен, чтобы знать, что массив, который вы копируете, всегда имеет длину 0. Он просто видит, что массив необходимо скопировать из памяти в хранилище, и не может сделать хорошую оценку газа. .
Тем не менее, приведенный выше простой код имеет примерно фиксированную стоимость газа, поэтому предупреждение можно игнорировать. Если вы подтвердите, что та же проблема вызывает предупреждение в вашем коде, я считаю, что вам также безопасно игнорировать его.
Если вы хотите избавиться от предупреждения, вы можете вместо этого написать этот код. Я подозреваю, что в любом случае это более эффективно с точки зрения газа:
FeatureData storage featureData = data[key];
featureData.state = State.Deployment;
featureData.backers.length = 0;
featureData.raised = 0;
featureData.prepaid = 0;
пользователь19510
FeatureData
предполагается копировать в хранилище из-заbackers
массива с динамическим размером . Не могли бы вы поделиться достаточным количеством кода, чтобы это можно было скомпилировать?4ntoine
пользователь19510