import { keccak256 } from 'ethereumjs-util' ; import { call , EIP1967BeaconNotFound , EIP1967ImplementationNotFound , getBeaconAddress , getImplementationAddress , UpgradesError , } from '.' ; import { EthereumProvider } from './provider' ; import { parseAddress } from './utils/address' ; export class InvalidBeacon extends UpgradesError { } param provider param beaconAddress returns throws export async function getImplementationAddressFromBeacon ( provider , beaconAddress ) { const implementationFunction = '0x' + keccak256 ( Buffer . from ( 'implementation()' ) ) . toString ( 'hex' ) . slice ( 0 , 8 ) ; let result ; try { const implAddress = await call ( provider , beaconAddress , implementationFunction ) ; result = parseAddress ( implAddress ) ; } catch ( e ) { if ( ! ( e . message . includes ( 'function selector was not recognized' ) || e . message . includes ( 'invalid opcode' ) || e . message . includes ( 'Transaction reverted' ) ) ) { throw e ; } } if ( result === undefined ) { throw new InvalidBeacon ( `Contract at ${ beaconAddress } doesn't look like a beacon` ) ; } return result ; } returns export async function getImplementationAddressFromProxy ( provider , proxyAddress ) { try { return await getImplementationAddress ( provider , proxyAddress ) ; } catch ( e ) { if ( e instanceof EIP1967ImplementationNotFound ) { try { const beaconAddress = await getBeaconAddress ( provider , proxyAddress ) ; return await getImplementationAddressFromBeacon ( provider , beaconAddress ) ; } catch ( e ) { if ( e instanceof EIP1967BeaconNotFound ) { return undefined ; } else { throw e ; } } } else { throw e ; } } }