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

     1  import { BigNumberish, BigNumber } from '@ethersproject/bignumber'
     2  import { keccak256 } from '@ethersproject/keccak256'
     3  import { defaultAbiCoder } from '@ethersproject/abi'
     4  
     5  import {
     6    decodeVersionedNonce,
     7    encodeCrossDomainMessageV0,
     8    encodeCrossDomainMessageV1,
     9  } from './encoding'
    10  
    11  /**
    12   * Bedrock output oracle data.
    13   */
    14  export interface BedrockOutputData {
    15    outputRoot: string
    16    l1Timestamp: number
    17    l2BlockNumber: number
    18    l2OutputIndex: number
    19  }
    20  
    21  /**
    22   * Bedrock state commitment
    23   */
    24  export interface OutputRootProof {
    25    version: string
    26    stateRoot: string
    27    messagePasserStorageRoot: string
    28    latestBlockhash: string
    29  }
    30  
    31  /**
    32   * Bedrock proof data required to finalize an L2 to L1 message.
    33   */
    34  export interface BedrockCrossChainMessageProof {
    35    l2OutputIndex: number
    36    outputRootProof: OutputRootProof
    37    withdrawalProof: string[]
    38  }
    39  
    40  /**
    41   * Parameters that govern the L2OutputOracle.
    42   */
    43  export type L2OutputOracleParameters = {
    44    submissionInterval: number
    45    startingBlockNumber: number
    46    l2BlockTime: number
    47  }
    48  
    49  /**
    50   * Hahses a cross domain message.
    51   *
    52   * @param nonce     The cross domain message nonce
    53   * @param sender    The sender of the cross domain message
    54   * @param target    The target of the cross domain message
    55   * @param value     The value being sent with the cross domain message
    56   * @param gasLimit  The gas limit of the cross domain execution
    57   * @param data      The data passed along with the cross domain message
    58   */
    59  export const hashCrossDomainMessage = (
    60    nonce: BigNumber,
    61    sender: string,
    62    target: string,
    63    value: BigNumber,
    64    gasLimit: BigNumber,
    65    message: string
    66  ) => {
    67    const { version } = decodeVersionedNonce(nonce)
    68    if (version.eq(0)) {
    69      return hashCrossDomainMessagev0(target, sender, message, nonce)
    70    } else if (version.eq(1)) {
    71      return hashCrossDomainMessagev1(
    72        nonce,
    73        sender,
    74        target,
    75        value,
    76        gasLimit,
    77        message
    78      )
    79    }
    80    throw new Error(`unknown version ${version.toString()}`)
    81  }
    82  
    83  /**
    84   * Hahses a V0 cross domain message
    85   *
    86   * @param target    The target of the cross domain message
    87   * @param sender    The sender of the cross domain message
    88   * @param message      The message passed along with the cross domain message
    89   * @param nonce     The cross domain message nonce
    90   */
    91  export const hashCrossDomainMessagev0 = (
    92    target: string,
    93    sender: string,
    94    message: string,
    95    nonce: BigNumber
    96  ) => {
    97    return keccak256(encodeCrossDomainMessageV0(target, sender, message, nonce))
    98  }
    99  
   100  /**
   101   * Hahses a V1 cross domain message
   102   *
   103   * @param nonce     The cross domain message nonce
   104   * @param sender    The sender of the cross domain message
   105   * @param target    The target of the cross domain message
   106   * @param value     The value being sent with the cross domain message
   107   * @param gasLimit  The gas limit of the cross domain execution
   108   * @param message      The message passed along with the cross domain message
   109   */
   110  export const hashCrossDomainMessagev1 = (
   111    nonce: BigNumber,
   112    sender: string,
   113    target: string,
   114    value: BigNumberish,
   115    gasLimit: BigNumberish,
   116    message: string
   117  ) => {
   118    return keccak256(
   119      encodeCrossDomainMessageV1(nonce, sender, target, value, gasLimit, message)
   120    )
   121  }
   122  
   123  /**
   124   * Hashes a withdrawal
   125   *
   126   * @param nonce     The cross domain message nonce
   127   * @param sender    The sender of the cross domain message
   128   * @param target    The target of the cross domain message
   129   * @param value     The value being sent with the cross domain message
   130   * @param gasLimit  The gas limit of the cross domain execution
   131   * @param message      The message passed along with the cross domain message
   132   */
   133  export const hashWithdrawal = (
   134    nonce: BigNumber,
   135    sender: string,
   136    target: string,
   137    value: BigNumber,
   138    gasLimit: BigNumber,
   139    message: string
   140  ): string => {
   141    const types = ['uint256', 'address', 'address', 'uint256', 'uint256', 'bytes']
   142    const encoded = defaultAbiCoder.encode(types, [
   143      nonce,
   144      sender,
   145      target,
   146      value,
   147      gasLimit,
   148      message,
   149    ])
   150    return keccak256(encoded)
   151  }
   152  
   153  /**
   154   * Hahses an output root proof
   155   *
   156   * @param proof OutputRootProof
   157   */
   158  export const hashOutputRootProof = (proof: OutputRootProof): string => {
   159    return keccak256(
   160      defaultAbiCoder.encode(
   161        ['bytes32', 'bytes32', 'bytes32', 'bytes32'],
   162        [
   163          proof.version,
   164          proof.stateRoot,
   165          proof.messagePasserStorageRoot,
   166          proof.latestBlockhash,
   167        ]
   168      )
   169    )
   170  }