@polygon-hermez/vm
Version:
An Ethereum VM implementation
188 lines (176 loc) • 6.05 kB
text/typescript
import { Address } from 'ethereumjs-util'
import Common from '@ethereumjs/common'
import { PrecompileInput, PrecompileFunc } from './types'
import { default as p1 } from './01-ecrecover'
import { default as p2 } from './02-sha256'
import { default as p3 } from './03-ripemd160'
import { default as p4 } from './04-identity'
import { default as p5 } from './05-modexp'
import { default as p6 } from './06-ecadd'
import { default as p7 } from './07-ecmul'
import { default as p8 } from './08-ecpairing'
import { default as p9 } from './09-blake2f'
import { default as pa } from './0a-bls12-g1add'
import { default as pb } from './0b-bls12-g1mul'
import { default as pc } from './0c-bls12-g1multiexp'
import { default as pd } from './0d-bls12-g2add'
import { default as pe } from './0e-bls12-g2mul'
import { default as pf } from './0f-bls12-g2multiexp'
import { default as p10 } from './10-bls12-pairing'
import { default as p11 } from './11-bls12-map-fp-to-g1'
import { default as p12 } from './12-bls12-map-fp2-to-g2'
import { default as p100 } from './100-p256verify'
interface Precompiles {
[key: string]: PrecompileFunc
}
interface PrecompileAvailability {
[key: string]: PrecompileAvailabilityCheckType
}
type PrecompileAvailabilityCheckType =
| PrecompileAvailabilityCheckTypeHardfork
| PrecompileAvailabilityCheckTypeEIP
enum PrecompileAvailabilityCheck {
EIP,
Hardfork,
}
interface PrecompileAvailabilityCheckTypeHardfork {
type: PrecompileAvailabilityCheck.Hardfork
param: string
}
interface PrecompileAvailabilityCheckTypeEIP {
type: PrecompileAvailabilityCheck.EIP
param: number
}
const ripemdPrecompileAddress = '0000000000000000000000000000000000000003'
const precompiles: Precompiles = {
'0000000000000000000000000000000000000001': p1,
'0000000000000000000000000000000000000002': p2,
[ripemdPrecompileAddress]: p3,
'0000000000000000000000000000000000000004': p4,
'0000000000000000000000000000000000000005': p5,
'0000000000000000000000000000000000000006': p6,
'0000000000000000000000000000000000000007': p7,
'0000000000000000000000000000000000000008': p8,
'0000000000000000000000000000000000000009': p9,
'000000000000000000000000000000000000000a': pa,
'000000000000000000000000000000000000000b': pb,
'000000000000000000000000000000000000000c': pc,
'000000000000000000000000000000000000000d': pd,
'000000000000000000000000000000000000000e': pe,
'000000000000000000000000000000000000000f': pf,
'0000000000000000000000000000000000000010': p10,
'0000000000000000000000000000000000000011': p11,
'0000000000000000000000000000000000000012': p12,
'0000000000000000000000000000000000000100': p100,
}
const precompileAvailability: PrecompileAvailability = {
'0000000000000000000000000000000000000001': {
type: PrecompileAvailabilityCheck.Hardfork,
param: 'chainstart',
},
'0000000000000000000000000000000000000002': {
type: PrecompileAvailabilityCheck.Hardfork,
param: 'chainstart',
},
[ripemdPrecompileAddress]: {
type: PrecompileAvailabilityCheck.Hardfork,
param: 'chainstart',
},
'0000000000000000000000000000000000000004': {
type: PrecompileAvailabilityCheck.Hardfork,
param: 'chainstart',
},
'0000000000000000000000000000000000000005': {
type: PrecompileAvailabilityCheck.Hardfork,
param: 'byzantium',
},
'0000000000000000000000000000000000000006': {
type: PrecompileAvailabilityCheck.Hardfork,
param: 'byzantium',
},
'0000000000000000000000000000000000000007': {
type: PrecompileAvailabilityCheck.Hardfork,
param: 'byzantium',
},
'0000000000000000000000000000000000000008': {
type: PrecompileAvailabilityCheck.Hardfork,
param: 'byzantium',
},
'0000000000000000000000000000000000000009': {
type: PrecompileAvailabilityCheck.Hardfork,
param: 'istanbul',
},
'000000000000000000000000000000000000000a': {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
'000000000000000000000000000000000000000b': {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
'000000000000000000000000000000000000000c': {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
'000000000000000000000000000000000000000d': {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
'000000000000000000000000000000000000000f': {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
'000000000000000000000000000000000000000e': {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
'0000000000000000000000000000000000000010': {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
'0000000000000000000000000000000000000011': {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
'0000000000000000000000000000000000000012': {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
'0000000000000000000000000000000000000100': {
type: PrecompileAvailabilityCheck.Hardfork, // Should be EIP
param: 'chainstart', // Should be 7212 but set chainstart for simplicity of implementation
},
}
function getPrecompile(address: Address, common: Common): PrecompileFunc {
const addr = address.buf.toString('hex')
if (precompiles[addr]) {
const availability = precompileAvailability[addr]
if (
(availability.type == PrecompileAvailabilityCheck.Hardfork &&
common.gteHardfork(availability.param)) ||
(availability.type == PrecompileAvailabilityCheck.EIP &&
common.eips().includes(availability.param))
) {
return precompiles[addr]
}
}
return precompiles['']
}
function getActivePrecompiles(common: Common): Address[] {
const activePrecompiles: Address[] = []
for (const addressString in precompiles) {
const address = new Address(Buffer.from(addressString, 'hex'))
if (getPrecompile(address, common)) {
activePrecompiles.push(address)
}
}
return activePrecompiles
}
export {
precompiles,
getPrecompile,
PrecompileFunc,
PrecompileInput,
ripemdPrecompileAddress,
getActivePrecompiles,
}