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 }