@ethereumjs/evm
Version:
JavaScript Ethereum Virtual Machine (EVM) implementation
58 lines • 2.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.precompile01 = precompile01;
const util_1 = require("@ethereumjs/util");
const evm_ts_1 = require("../evm.js");
const index_ts_1 = require("./index.js");
const util_ts_1 = require("./util.js");
function precompile01(opts) {
const pName = (0, index_ts_1.getPrecompileName)('01');
const ecrecoverFunction = opts.common.customCrypto.ecrecover ?? util_1.ecrecover;
const gasUsed = opts.common.param('ecRecoverGas');
if (!(0, util_ts_1.gasLimitCheck)(opts, gasUsed, pName)) {
return (0, evm_ts_1.OOGResult)(opts.gasLimit);
}
const data = (0, util_1.setLengthRight)(opts.data, 128, { allowTruncate: true });
const msgHash = data.subarray(0, 32);
const v = data.subarray(32, 64);
const vBigInt = (0, util_1.bytesToBigInt)(v);
// Guard against util's `ecrecover`: without providing chainId this will return
// a signature in most of the cases in the cases that `v=0` or `v=1`
// However, this should throw, only 27 and 28 is allowed as input
if (vBigInt !== util_1.BIGINT_27 && vBigInt !== util_1.BIGINT_28) {
if (opts._debug !== undefined) {
opts._debug(`${pName} failed: v neither 27 nor 28`);
}
return {
executionGasUsed: gasUsed,
returnValue: new Uint8Array(),
};
}
const r = data.subarray(64, 96);
const s = data.subarray(96, 128);
let publicKey;
try {
if (opts._debug !== undefined) {
opts._debug(`${pName}: PK recovery with msgHash=${(0, util_1.bytesToHex)(msgHash)} v=${(0, util_1.bytesToHex)(v)} r=${(0, util_1.bytesToHex)(r)}s=${(0, util_1.bytesToHex)(s)}}`);
}
publicKey = ecrecoverFunction(msgHash, (0, util_1.bytesToBigInt)(v), r, s);
}
catch {
if (opts._debug !== undefined) {
opts._debug(`${pName} failed: PK recovery failed`);
}
return {
executionGasUsed: gasUsed,
returnValue: new Uint8Array(0),
};
}
const address = (0, util_1.setLengthLeft)((0, util_1.publicToAddress)(publicKey), 32);
if (opts._debug !== undefined) {
opts._debug(`${pName} return address=${(0, util_1.bytesToHex)(address)}`);
}
return {
executionGasUsed: gasUsed,
returnValue: address,
};
}
//# sourceMappingURL=01-ecrecover.js.map