У меня есть контракт, который выполняет довольно сложные вычисления с некоторыми промежуточными вычислениями, и я сталкиваюсь с проблемой «слишком глубокого стека».
Я попытался использовать массив памяти внутри функции для сохранения временных «локальных переменных» вместо создания новых локальных переменных.
Например, вместо:
function usingLocalVars() {
// Get 3 uint values from a getter function call from another contract
// and save as local variables uint a, uint b, uint c:
var(a, b, c) = otherContract.getter(param);
// Perform some computation an a, b, and c and save as another variable d
uint d = someOperation(a, b, c);
/** other code with a return **/
}
Переписано с использованием массива памяти:
function usingMemoryArray() {
// Get 3 uint values from a getter function call from another contract
// and store into memory array temp:
// create memory array
uint[4] memory temp;
// save values into memory array
(temp[0], temp[1], temp[2]) = otherContract.getter(param);
// Perform some computation an a, b, and c and save into temp[3]
temp[3] = someOperation(temp[0], temp[1], temp[2]);
/** other code with a return **/
}
Итак, что я пытался сделать:
returns (uint x, uint y, uint z)
=>returns (uint, uint, uint)
Текущая сводка функций:
int
локальная переменнаяsomeOperation()
) выше. Может ли это быть еще одной причиной этой проблемы? Необходимо ограничить локальную переменную, используемую в вызовах других методов (например, someOperation()
)?Действительно ли использование массива памяти, как я упоминал выше, помогает решить эту проблему (слишком глубокий стек)?
Таким образом, мои назначения временных переменных вызывали проблему. Это работает, если ограничиться 8 заданиями одновременно:
Это не удается (9 присвоений переменных):
(temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], temp[7], temp[8]) = (1, 2, 3, 4, 5, 6, 7, 8, 9);
Но это работает (8 заданий одновременно ):
(temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], temp[7]) = (1, 2, 3, 4, 5, 6, 7, 8);
(temp[8], temp[9], temp[10], temp[11], temp[12], temp[13], temp[14], temp[15]) = (9, 10, 11, 12, 13, 14, 15, 16);
Кроме того, использование массива памяти позволяет избежать слишком глубокого стека локальных переменных .
Возможно, вы пробовали это, но некоторые отладки в Remix с пустыми getter()
и someOperation()
функциями, которые просто возвращают значения, показывают, что максимальная глубина стека достигает 12 элементов, когда я использую первый метод, и только 9 для второго. Мне еще предстоит полностью понять различия, но рассмотрите возможность использования ремикса и проверки экрана отладки, если вы еще этого не сделали.
пользователь19510
Карлолм
пользователь19510
пользователь19510
Карлолм