Непредсказуемая ошибка состояний при рефакторинге смарт-контрактов

Функции смарт-контракта Ethereum ограничены примерно 16 локальными переменными. Когда они превышают это число, stack is too deepгенерируется ошибка.

Решение состоит в том, чтобы реорганизовать большие функции в более мелкие. Например:

Contract A{
   function B(p1,p2,p3...pn){
   }
}

Может развиваться как:

Contract A{
   function B1(p1,p2){
   }
   function B2(p3,p4){
   }
   ...

}

Теперь предположим, что некоторые функции зависят от результатов других. Другими словами, изменение состояния, вызванное функцией, влияет на то, как действует другая функция.

Эта проблема, о которой я думаю, представляет собой непредсказуемое состояние, обсуждаемое в этой статье , в которой говорится:

В общем, когда пользователь отправляет транзакцию в сеть, чтобы вызвать какой-то контракт, он не может быть уверен, что транзакция будет запущена в том же состоянии, в котором контракт находился во время отправки этой транзакции.

Как мы можем гарантировать, что пользователь, который хочет совершить транзакцию с функцией, B1затем захочет совершить транзакцию с функцией B2без того, чтобы кто-то другой изменил состояние, вызванное B1повторной транзакцией?

Ответы (1)

Если некоторые из переменных являются временными и могут содержаться внутри своих функций, вы можете вызывать B1()изнутри B2(), что позволяет обойти ограничение глубины стека, сохраняя при этом порядок выполнения.

Если вам нужно разделить его на два вызова, и важно, в каком порядке они вызываются, вам может потребоваться самостоятельно управлять зависимостью. Например, запишите переменную B1()и зарегистрируйте ее B2(), вызывая, revertесли она не была записана.

Можете ли вы уточнить, что такое A1()?
Извините, я имел в виду B1 и B2, т.е. 2 функции в примере. Отредактировано.