@polygon-hermez/vm
Version:
An Ethereum VM implementation
42 lines (35 loc) • 1.08 kB
text/typescript
import { setLengthLeft, setLengthRight, ecrecover, publicToAddress, BN } from 'ethereumjs-util'
import { PrecompileInput } from './types'
import { OOGResult, ExecResult } from '../evm'
const assert = require('assert')
export default function (opts: PrecompileInput): ExecResult {
assert(opts.data)
const gasUsed = new BN(opts._common.param('gasPrices', 'ecRecover'))
if (opts.gasLimit.lt(gasUsed)) {
return OOGResult(opts.gasLimit)
}
const data = setLengthRight(opts.data, 128)
const msgHash = data.slice(0, 32)
const v = data.slice(32, 64)
const r = data.slice(64, 96)
const s = data.slice(96, 128)
// Reduce counters
opts._VM.vcm.computeFunctionCounters('preECRecover', {
v: new BN(v).toString('hex'),
r: new BN(r).toString('hex'),
s: new BN(s).toString('hex'),
})
let publicKey
try {
publicKey = ecrecover(msgHash, new BN(v), r, s)
} catch (e: any) {
return {
gasUsed,
returnValue: Buffer.alloc(0),
}
}
return {
gasUsed,
returnValue: setLengthLeft(publicToAddress(publicKey), 32),
}
}