github.com/ethereum-optimism/optimism@v1.7.2/packages/core-utils/src/optimism/fees.ts (about)

     1  /**
     2   * Fee related serialization and deserialization
     3   */
     4  
     5  import { BigNumber } from '@ethersproject/bignumber'
     6  
     7  import { remove0x } from '../common'
     8  
     9  export const txDataZeroGas = 4
    10  export const txDataNonZeroGasEIP2028 = 16
    11  const big10 = BigNumber.from(10)
    12  
    13  export const scaleDecimals = (
    14    value: number | BigNumber,
    15    decimals: number | BigNumber
    16  ): BigNumber => {
    17    value = BigNumber.from(value)
    18    decimals = BigNumber.from(decimals)
    19    // 10**decimals
    20    const divisor = big10.pow(decimals)
    21    return value.div(divisor)
    22  }
    23  
    24  // data is the RLP encoded unsigned transaction
    25  export const calculateL1GasUsed = (
    26    data: string | Buffer,
    27    overhead: number | BigNumber
    28  ): BigNumber => {
    29    const [zeroes, ones] = zeroesAndOnes(data)
    30    const zeroesCost = zeroes * txDataZeroGas
    31    // Add a buffer to account for the signature
    32    const onesCost = (ones + 68) * txDataNonZeroGasEIP2028
    33    return BigNumber.from(onesCost).add(zeroesCost).add(overhead)
    34  }
    35  
    36  export const calculateL1Fee = (
    37    data: string | Buffer,
    38    overhead: number | BigNumber,
    39    l1GasPrice: number | BigNumber,
    40    scalar: number | BigNumber,
    41    decimals: number | BigNumber
    42  ): BigNumber => {
    43    const l1GasUsed = calculateL1GasUsed(data, overhead)
    44    const l1Fee = l1GasUsed.mul(l1GasPrice)
    45    const scaled = l1Fee.mul(scalar)
    46    const result = scaleDecimals(scaled, decimals)
    47    return result
    48  }
    49  
    50  // Count the number of zero bytes and non zero bytes in a buffer
    51  export const zeroesAndOnes = (data: Buffer | string): Array<number> => {
    52    if (typeof data === 'string') {
    53      data = Buffer.from(remove0x(data), 'hex')
    54    }
    55    let zeros = 0
    56    let ones = 0
    57    for (const byte of data) {
    58      if (byte === 0) {
    59        zeros++
    60      } else {
    61        ones++
    62      }
    63    }
    64    return [zeros, ones]
    65  }
    66  
    67  /**
    68   * Computes the L1 calldata cost of bytes based
    69   * on the London hardfork.
    70   *
    71   * @param data {Buffer|string} Bytes
    72   * @returns {BigNumber} Gas consumed by the bytes
    73   */
    74  export const calldataCost = (data: Buffer | string): BigNumber => {
    75    const [zeros, ones] = zeroesAndOnes(data)
    76    const zeroCost = BigNumber.from(zeros).mul(txDataZeroGas)
    77    const nonZeroCost = BigNumber.from(ones).mul(txDataNonZeroGasEIP2028)
    78    return zeroCost.add(nonZeroCost)
    79  }