2025-04-19 15:38:48 +08:00

87 lines
2.9 KiB
JavaScript

import { SECP256K1_ORDER_DIV_2, bigIntToUnpaddedBytes, ecrecover } from '@ethereumjs/util';
import { keccak256 } from 'ethereum-cryptography/keccak.js';
import { BaseTransaction } from '../baseTransaction.js';
import { Capability } from '../types.js';
export function errorMsg(tx, msg) {
return `${msg} (${tx.errorStr()})`;
}
export function isSigned(tx) {
const { v, r, s } = tx;
if (v === undefined || r === undefined || s === undefined) {
return false;
}
else {
return true;
}
}
/**
* The amount of gas paid for the data in this tx
*/
export function getDataFee(tx, extraCost) {
if (tx.cache.dataFee && tx.cache.dataFee.hardfork === tx.common.hardfork()) {
return tx.cache.dataFee.value;
}
const cost = BaseTransaction.prototype.getDataFee.bind(tx)() + (extraCost ?? 0n);
if (Object.isFrozen(tx)) {
tx.cache.dataFee = {
value: cost,
hardfork: tx.common.hardfork(),
};
}
return cost;
}
export function hash(tx) {
if (!tx.isSigned()) {
const msg = errorMsg(tx, 'Cannot call hash method if transaction is not signed');
throw new Error(msg);
}
const keccakFunction = tx.common.customCrypto.keccak256 ?? keccak256;
if (Object.isFrozen(tx)) {
if (!tx.cache.hash) {
tx.cache.hash = keccakFunction(tx.serialize());
}
return tx.cache.hash;
}
return keccakFunction(tx.serialize());
}
/**
* EIP-2: All transaction signatures whose s-value is greater than secp256k1n/2are considered invalid.
* Reasoning: https://ethereum.stackexchange.com/a/55728
*/
export function validateHighS(tx) {
const { s } = tx;
if (tx.common.gteHardfork('homestead') && s !== undefined && s > SECP256K1_ORDER_DIV_2) {
const msg = errorMsg(tx, 'Invalid Signature: s-values greater than secp256k1n/2 are considered invalid');
throw new Error(msg);
}
}
export function getSenderPublicKey(tx) {
if (tx.cache.senderPubKey !== undefined) {
return tx.cache.senderPubKey;
}
const msgHash = tx.getMessageToVerifySignature();
const { v, r, s } = tx;
validateHighS(tx);
try {
const ecrecoverFunction = tx.common.customCrypto.ecrecover ?? ecrecover;
const sender = ecrecoverFunction(msgHash, v, bigIntToUnpaddedBytes(r), bigIntToUnpaddedBytes(s), tx.supports(Capability.EIP155ReplayProtection) ? tx.common.chainId() : undefined);
if (Object.isFrozen(tx)) {
tx.cache.senderPubKey = sender;
}
return sender;
}
catch (e) {
const msg = errorMsg(tx, 'Invalid Signature');
throw new Error(msg);
}
}
export function getEffectivePriorityFee(gasPrice, baseFee) {
if (baseFee !== undefined && baseFee > gasPrice) {
throw new Error('Tx cannot pay baseFee');
}
if (baseFee === undefined) {
return gasPrice;
}
return gasPrice - baseFee;
}
//# sourceMappingURL=legacy.js.map