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 }