Как мне устранить эту ошибку компилятора Hardhat? (Слишком глубокий стек при компиляции встроенной сборки)

#ethereum #solidity #smartcontracts #nft #hardhat

#ethereum #надежность #smartcontracts #nft #жесткий диск

Вопрос:

Я анализирую смарт-контракты Chainrunners, поэтому я зашел на Etherscan и скопировал проверенный исходный код контракта.

Когда я попытался скомпилировать без solidity optimizer, я получил это предупреждение:

 thatguyintech@albert chainrunners % npx hardhat compile
Compiling 5 files with 0.8.4
Warning: Unused local variable.
   --> contracts/ChainRunnersBaseRenderer.sol:232:124:
    |
232 |  ... kenPalettes, uint8 numTokenLayers, string[NUM_LAYERS] memory traitTypes) = getTokenData(_dna);
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


Warning: Contract code size exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries.
  --> contracts/ChainRunnersBaseRenderer.sol:48:1:
   |
48 | contract ChainRunnersBaseRenderer is Ownable, ReentrancyGuard {
   | ^ (Relevant source part starts here and spans across multiple lines).
 

Итак, я попытался включить оптимизатор в соответствии с официальной документацией Hardhat: https://hardhat.org/config /

Итак, вот как hardhat.config.js выглядит моя конфигурация жесткого диска:

 /**
 * @type import('hardhat/config').HardhatUserConfig
 */
module.exports = {
  solidity: {
    version:  "0.8.4",
    settings: {
      optimizer: {
        enabled: true,
        runs: 2000,
      }
    }
  }
};
 

Итак, теперь я получаю этот жесткий диск CompilerError при попытке запуска npx hardhat compile :

 thatguyintech@albert chainrunners % npx hardhat compile
Compiling 5 files with 0.8.4
CompilerError: Stack too deep when compiling inline assembly: Variable value0 is 3 slot(s) too deep inside the stack.
 

Кто-нибудь знает, как я могу это решить? Из нескольких поисковых запросов Google в потоках, связанных с hardhat, кажется, что включение оптимизатора должно быть решением этой проблемы, поэтому я в замешательстве.

Вот пример, который я нашел на форумах OpenZeppelin, который у меня не работает: https://forum.openzeppelin.com/t/stack-to-deep-when-compiling-inline-assembly/11391/11

Комментарии:

1. Я также только что понял, что это не фактический контракт nft Chainrunners — это контракт средства визуализации. Теперь мне нужно посмотреть, как контракт nft использует средство визуализации…

Ответ №1:

Ах, оказывается, на странице Etherscan есть раздел, который показывает точный набор solidity optimizer. (h/t @alcuadadro)

Это выглядит примерно так:

введите описание изображения здесь

И поэтому я скопировал это в свой hardhat.config.js :

 /**
 * @type import('hardhat/config').HardhatUserConfig
 */
module.exports = {
  solidity: {
    version:  "0.8.4",
    settings: {
      optimizer: {
        enabled: true,
        runs: 2000,
        details: {
          yul: true,
          yulDetails: {
            stackAllocation: true,
            optimizerSteps: "dhfoDgvulfnTUtnIf"
          }
        }
      }
    },
  },
};
 

и это сделало свое дело!

хотя понятия не yul имею, о чем идет речь

Комментарии:

1. yul: true и stackAllocation: true являются просто значениями по умолчанию, когда оптимизатор включен. Они здесь лишние, но их добавление не повредит.

2. optimizerSteps: "dhfoDgvulfnTUtnIf" с другой стороны, это расширенная оптимизация. Это отключает большую часть последовательности шагов оптимизатора . Последовательность по умолчанию немного длиннее. Я бы не рекомендовал это в качестве общего решения ошибки «Слишком глубокий стек» (в конечном итоге она будет решена в компиляторе), но довольно интересно, что отключение этих оптимизаций действительно помогает в этом случае.

3. спасибо за ясность! @cameel