Optimizer in solidity

Optimizer in solidity

  • 合约设计及实现变迁

    v1.x版本实现,每次创建同样的合约


    v2.x版本实现, 逻辑单独抽象成library,每次创建合约仅包含storage variables


    v3.x版本实现, 分为代理合约和逻辑合约,每次创建代理合约(不包含逻辑和storage variables)


    summary: 如果某个合约需要部署很多次,可以采用library或proxy来部署合约,每个合约仅是初始化值不同,采用proxy模式更好

    contract Table is Proxy {
    
        bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
    
        constructor(
            address _implAddr
        ) {
            _setImplementation(_implAddr);
        }
    
        function _implementation() internal view override returns (address) {
            return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
        }
    
        function _setImplementation(address newImplementation) private {
            require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
            StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
        }
    
    }
    
    constract Logic {
    }
    
    contract Table {
        using TableLogic for TableLogic.TableInfo;
        TableLogic.TableInfo tableInfo;
    }
    
    library TableLogic {
    }    
    
  • solidity中的optimizer

    大部分论述来自 https://docs.soliditylang.org/en/v0.8.17/internals/optimizer.html

    solidity使用两种编译器:The opcode-based optimizer 和 The Yul-based optimizer.

    solidity产生EVM bytecode有两种方式: solidity语言直接翻译成evm opcode, 或先翻译成Yul后再翻译成evm opcode(IR-based code generator).

    The IR-based code generator不仅更透明和可审计的,而且可以跨函数优化code。同样的solidity代码可能产生不同的语义变化( https://docs.soliditylang.org/en/v0.8.17/ir-breaking-changes.html) .

    • The opcode-based optimizer

      这个优化器主要是简化相同的代码,删除无用的代码. 简化规则参考( https://github.com/ethereum/solidity/blob/develop/libevmasm/RuleList.h )

    • The Yul-based optimizer

    • Optimizer Parameter Runs

      这个参数指定了部署代码在合约生命周期内执行的频率,是code size(deploy cost)和code execution(cost after deployment)的权衡

      参数范围: [1, 2^32-1]

    • 使用编译器配置

      "optimizer": {
        // Disabled by default.
        // NOTE: enabled=false still leaves some optimizations on. See comments below.
        // WARNING: Before version 0.8.6 omitting the 'enabled' key was not equivalent to setting
        // it to false and would actually disable all the optimizations.
        "enabled": true,
        // Optimize for how many times you intend to run the code.
        // Lower values will optimize more for initial deployment cost, higher
        // values will optimize more for high-frequency usage.
        "runs": 200,
        // Switch optimizer components on or off in detail.
        // The "enabled" switch above provides two defaults which can be
        // tweaked here. If "details" is given, "enabled" can be omitted.
        "details": {
          // The peephole optimizer is always on if no details are given,
          // use details to switch it off.
          "peephole": true,
          // The inliner is always on if no details are given,
          // use details to switch it off.
          "inliner": true,
          // The unused jumpdest remover is always on if no details are given,
          // use details to switch it off.
          "jumpdestRemover": true,
          // Sometimes re-orders literals in commutative operations.
          "orderLiterals": false,
          // Removes duplicate code blocks
          "deduplicate": false,
          // Common subexpression elimination, this is the most complicated step but
          // can also provide the largest gain.
          "cse": false,
          // Optimize representation of literal numbers and strings in code.
          "constantOptimizer": false,
          // The new Yul optimizer. Mostly operates on the code of ABI coder v2
          // and inline assembly.
          // It is activated together with the global optimizer setting
          // and can be deactivated here.
          // Before Solidity 0.6.0 it had to be activated through this switch.
          "yul": false,
          // Tuning options for the Yul optimizer.
          "yulDetails": {
            // Improve allocation of stack slots for variables, can free up stack slots early.
            // Activated by default if the Yul optimizer is activated.
            "stackAllocation": true,
            // Select optimization steps to be applied.
            // Optional, the optimizer will use the default sequence if omitted.
            "optimizerSteps": "dhfoDgvulfnTUtnIf..."
          }
        }
      }
      

resources