UNPKG

@ethereumjs/evm

Version:
345 lines (324 loc) 9.04 kB
import { Hardfork } from '@ethereumjs/common' import { type Address, type PrefixedHexString, bytesToUnprefixedHex } from '@ethereumjs/util' import { precompile0a } from './0a-kzg-point-evaluation.ts' import { precompile0b } from './0b-bls12-g1add.ts' import { precompile0c } from './0c-bls12-g1msm.ts' import { precompile0d } from './0d-bls12-g2add.ts' import { precompile0e } from './0e-bls12-g2msm.ts' import { precompile0f } from './0f-bls12-pairing.ts' import { precompile01 } from './01-ecrecover.ts' import { precompile02 } from './02-sha256.ts' import { precompile03 } from './03-ripemd160.ts' import { precompile04 } from './04-identity.ts' import { precompile05 } from './05-modexp.ts' import { precompile06 } from './06-bn254-add.ts' import { precompile07 } from './07-bn254-mul.ts' import { precompile08 } from './08-bn254-pairing.ts' import { precompile09 } from './09-blake2f.ts' import { precompile10 } from './10-bls12-map-fp-to-g1.ts' import { precompile11 } from './11-bls12-map-fp2-to-g2.ts' import { precompile100 } from './100-p256verify.ts' import { MCLBLS, NobleBLS } from './bls12_381/index.ts' import { NobleBN254, RustBN254 } from './bn254/index.ts' import type { Common } from '@ethereumjs/common' import type { PrecompileFunc, PrecompileInput } from './types.ts' interface PrecompileEntry { address: string check: PrecompileAvailabilityCheckType precompile: PrecompileFunc name: string } interface Precompiles { [key: string]: PrecompileFunc } type PrecompileAvailabilityCheckType = | PrecompileAvailabilityCheckTypeHardfork | PrecompileAvailabilityCheckTypeEIP export type PrecompileAvailabilityCheck = (typeof PrecompileAvailabilityCheck)[keyof typeof PrecompileAvailabilityCheck] export const PrecompileAvailabilityCheck = { EIP: 'eip', Hardfork: 'hardfork', } as const interface PrecompileAvailabilityCheckTypeHardfork { type: typeof PrecompileAvailabilityCheck.Hardfork param: string } interface PrecompileAvailabilityCheckTypeEIP { type: typeof PrecompileAvailabilityCheck.EIP param: number } const BYTES_19 = '00000000000000000000000000000000000000' const ripemdPrecompileAddress = BYTES_19 + '03' const precompileEntries: PrecompileEntry[] = [ { address: BYTES_19 + '01', check: { type: PrecompileAvailabilityCheck.Hardfork, param: Hardfork.Chainstart, }, precompile: precompile01, name: 'ECRECOVER (0x01)', }, { address: BYTES_19 + '02', check: { type: PrecompileAvailabilityCheck.Hardfork, param: Hardfork.Chainstart, }, precompile: precompile02, name: 'SHA256 (0x02)', }, { address: BYTES_19 + '03', check: { type: PrecompileAvailabilityCheck.Hardfork, param: Hardfork.Chainstart, }, precompile: precompile03, name: 'RIPEMD160 (0x03)', }, { address: BYTES_19 + '04', check: { type: PrecompileAvailabilityCheck.Hardfork, param: Hardfork.Chainstart, }, precompile: precompile04, name: 'IDENTITY (0x04)', }, { address: BYTES_19 + '05', check: { type: PrecompileAvailabilityCheck.Hardfork, param: Hardfork.Byzantium, }, precompile: precompile05, name: 'MODEXP (0x05)', }, { address: BYTES_19 + '06', check: { type: PrecompileAvailabilityCheck.Hardfork, param: Hardfork.Byzantium, }, precompile: precompile06, name: 'BN254_ADD (0x06)', }, { address: BYTES_19 + '07', check: { type: PrecompileAvailabilityCheck.Hardfork, param: Hardfork.Byzantium, }, precompile: precompile07, name: 'BN254_MUL (0x07)', }, { address: BYTES_19 + '08', check: { type: PrecompileAvailabilityCheck.Hardfork, param: Hardfork.Byzantium, }, precompile: precompile08, name: 'BN254_PAIRING (0x08)', }, { address: BYTES_19 + '09', check: { type: PrecompileAvailabilityCheck.Hardfork, param: Hardfork.Istanbul, }, precompile: precompile09, name: 'BLAKE2f (0x09)', }, { address: BYTES_19 + '0a', check: { type: PrecompileAvailabilityCheck.EIP, param: 4844, }, precompile: precompile0a, name: 'KZG_POINT_EVALUATION (0x0a)', }, { address: BYTES_19 + '0b', check: { type: PrecompileAvailabilityCheck.EIP, param: 2537, }, precompile: precompile0b, name: 'BLS12_G1ADD (0x0b)', }, { address: BYTES_19 + '0c', check: { type: PrecompileAvailabilityCheck.EIP, param: 2537, }, precompile: precompile0c, name: 'BLS12_G1MSM (0x0c)', }, { address: BYTES_19 + '0d', check: { type: PrecompileAvailabilityCheck.EIP, param: 2537, }, precompile: precompile0d, name: 'BLS12_G2ADD (0x0d)', }, { address: BYTES_19 + '0e', check: { type: PrecompileAvailabilityCheck.EIP, param: 2537, }, precompile: precompile0e, name: 'BLS12_G2MSM (0x0e)', }, { address: BYTES_19 + '0f', check: { type: PrecompileAvailabilityCheck.EIP, param: 2537, }, precompile: precompile0f, name: 'BLS12_PAIRING (0x0f)', }, { address: BYTES_19 + '10', check: { type: PrecompileAvailabilityCheck.EIP, param: 2537, }, precompile: precompile10, name: 'BLS12_MAP_FP_TO_G1 (0x10)', }, { address: BYTES_19 + '11', check: { type: PrecompileAvailabilityCheck.EIP, param: 2537, }, precompile: precompile11, name: 'BLS12_MAP_FP_TO_G2 (0x11)', }, { address: '0000000000000000000000000000000000000100', check: { type: PrecompileAvailabilityCheck.EIP, param: 7951, }, precompile: precompile100, name: 'P256VERIFY (0x100)', }, ] const precompiles: Precompiles = { [BYTES_19 + '01']: precompile01, [BYTES_19 + '02']: precompile02, [ripemdPrecompileAddress]: precompile03, [BYTES_19 + '04']: precompile04, [BYTES_19 + '05']: precompile05, [BYTES_19 + '06']: precompile06, [BYTES_19 + '07']: precompile07, [BYTES_19 + '08']: precompile08, [BYTES_19 + '09']: precompile09, [BYTES_19 + '0a']: precompile0a, [BYTES_19 + '0b']: precompile0b, [BYTES_19 + '0c']: precompile0c, [BYTES_19 + '0d']: precompile0d, [BYTES_19 + '0e']: precompile0e, [BYTES_19 + '0f']: precompile0f, [BYTES_19 + '10']: precompile10, [BYTES_19 + '11']: precompile11, '0000000000000000000000000000000000000100': precompile100, } /** * Specifies a precompile to remove from the EVM. * The address can be an `Address` instance or a `0x`-prefixed hex string. */ type DeletePrecompile = { address: Address | PrefixedHexString } /** * Specifies a precompile to add to (or override in) the EVM. * The address can be an `Address` instance or a `0x`-prefixed hex string. */ type AddPrecompile = { address: Address | PrefixedHexString function: PrecompileFunc } /** * A custom precompile entry: either an addition/override or a deletion. * * ```ts * // Add a custom precompile at a new address * const add: CustomPrecompile = { * address: '0x0000000000000000000000000000000000ff0001', * function: myPrecompileImpl, * } * // Delete an existing precompile * const del: CustomPrecompile = { * address: '0x0000000000000000000000000000000000000002', * } * ``` */ type CustomPrecompile = AddPrecompile | DeletePrecompile function resolvePrecompileAddress(address: Address | PrefixedHexString): string { if (typeof address === 'string') { return address.slice(2).padStart(40, '0').toLowerCase() } return bytesToUnprefixedHex(address.bytes) } function getActivePrecompiles( common: Common, customPrecompiles?: CustomPrecompile[], ): Map<string, PrecompileFunc> { const precompileMap = new Map() if (customPrecompiles) { for (const precompile of customPrecompiles) { precompileMap.set( resolvePrecompileAddress(precompile.address), 'function' in precompile ? precompile.function : undefined, ) } } for (const entry of precompileEntries) { if (precompileMap.has(entry.address)) { continue } const type = entry.check.type if ( (type === PrecompileAvailabilityCheck.Hardfork && common.gteHardfork(entry.check.param)) || (entry.check.type === PrecompileAvailabilityCheck.EIP && common.isActivatedEIP(entry.check.param)) ) { precompileMap.set(entry.address, entry.precompile) } } return precompileMap } function getPrecompileName(addressUnprefixedStr: string) { if (addressUnprefixedStr.length < 40) { addressUnprefixedStr = addressUnprefixedStr.padStart(40, '0') } for (const entry of precompileEntries) { if (entry.address === addressUnprefixedStr) { return entry.name } } return '' } export { getActivePrecompiles, getPrecompileName, MCLBLS, NobleBLS, NobleBN254, precompileEntries, precompiles, ripemdPrecompileAddress, RustBN254, } export type { AddPrecompile, CustomPrecompile, DeletePrecompile, PrecompileFunc, PrecompileInput }