Commit 584cbc25 authored by kf's avatar kf Committed by Kelvin Fichter

feat: clean up and comment aliasing utils

parent b4d9d539
---
'@eth-optimism/core-utils': patch
---
Clean up the L1 => L2 address aliasing utilities
import { ethers } from 'ethers'
import { bnToAddress } from './bn'
// Constant representing the alias to apply to the msg.sender when a contract sends an L1 => L2
// message. We need this aliasing scheme because a contract can be deployed to the same address
// on both L1 and L2 but with different bytecode (address is not dependent on bytecode when using
// the standard CREATE opcode). We want to treat L1 contracts as having a different address while
// still making it possible for L2 contracts to easily reverse the aliasing scheme and figure out
// the real address of the contract that sent the L1 => L2 message.
export const L1_TO_L2_ALIAS_OFFSET =
'0x1111000000000000000000000000000000001111'
export const bnToAddress = (bn: ethers.BigNumber | number): string => {
bn = ethers.BigNumber.from(bn)
if (bn.isNegative()) {
bn = ethers.BigNumber.from('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')
.add(bn)
.add(1)
}
const addr = bn.toHexString().slice(2).padStart(40, '0')
return ethers.utils.getAddress(
'0x' + addr.slice(addr.length - 40, addr.length)
)
}
/**
* Applies the L1 => L2 aliasing scheme to an address.
*
* @param address Address to apply the scheme to.
* @returns Address with the scheme applied.
*/
export const applyL1ToL2Alias = (address: string): string => {
if (!ethers.utils.isAddress(address)) {
throw new Error(`not a valid address: ${address}`)
......@@ -25,6 +24,12 @@ export const applyL1ToL2Alias = (address: string): string => {
return bnToAddress(ethers.BigNumber.from(address).add(L1_TO_L2_ALIAS_OFFSET))
}
/**
* Reverses the L1 => L2 aliasing scheme from an address.
*
* @param address Address to reverse the scheme from.
* @returns Alias with the scheme reversed.
*/
export const undoL1ToL2Alias = (address: string): string => {
if (!ethers.utils.isAddress(address)) {
throw new Error(`not a valid address: ${address}`)
......
import { ethers } from 'ethers'
import { remove0x, add0x } from './common/hex-strings'
/**
* Converts an ethers BigNumber into an equivalent Ethereum address representation.
*
* @param bn BigNumber to convert to an address.
* @return BigNumber converted to an address, represented as a hex string.
*/
export const bnToAddress = (bn: ethers.BigNumber | number): string => {
// Coerce numbers into a BigNumber.
bn = ethers.BigNumber.from(bn)
// Negative numbers are converted to addresses by adding MAX_ADDRESS + 1.
// TODO: Explain this in more detail, it's basically just matching the behavior of doing
// addr(uint256(addr) - some_number) in Solidity where some_number > uint256(addr).
if (bn.isNegative()) {
bn = ethers.BigNumber.from('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')
.add(bn)
.add(1)
}
// Convert to a hex string
let addr = bn.toHexString()
// Remove leading 0x so we can mutate the address a bit
addr = remove0x(addr)
// Make sure it's 40 characters (= 20 bytes)
addr = addr.padStart(40, '0')
// Only take the last 40 characters (= 20 bytes)
addr = addr.slice(addr.length - 40, addr.length)
// Add 0x again
addr = add0x(addr)
// Convert into a checksummed address
addr = ethers.utils.getAddress(addr)
return addr
}
......@@ -8,3 +8,4 @@ export * from './fees'
export * from './provider'
export * from './alias'
export * from './types'
export * from './bn'
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment