@tevm/utils
Version:
A custom implementation of ethereumjs blockchain
551 lines (546 loc) • 17.5 kB
JavaScript
;
var errors = require('@tevm/errors');
var abitype = require('abitype');
var accounts = require('viem/accounts');
var utils = require('viem/utils');
var util = require('@ethereumjs/util');
// src/Bloom.ts
// src/Bloom.ts
var zeros = (bytes) => {
return new Uint8Array(bytes);
};
var BYTE_SIZE = 256;
var Bloom = class {
bitvector;
/**
* Represents a Bloom filter.
* @throws {InvalidBytesSizeError} If the byte size of the bitvector is not 256.
*/
constructor(bitvector) {
if (!bitvector) {
this.bitvector = zeros(BYTE_SIZE);
} else {
if (bitvector.length !== BYTE_SIZE) throw new errors.InvalidBytesSizeError(BYTE_SIZE, bitvector.length);
this.bitvector = bitvector;
}
}
/**
* Adds an element to a bit vector of a 64 byte bloom filter.
* @param e - The element to add
* @throws {never}
*/
add(e) {
const eBytes = utils.hexToBytes(utils.keccak256(e));
const mask = 2047;
for (let i = 0; i < 3; i++) {
const first2bytes = new DataView(eBytes.buffer).getUint16(i * 2);
const loc = mask & first2bytes;
const byteLoc = loc >> 3;
const bitLoc = 1 << loc % 8;
let item = this.bitvector[BYTE_SIZE - byteLoc - 1];
if (item === void 0) {
throw new errors.DefensiveNullCheckError("item is not defined. There is a bug in the implementation");
}
item |= bitLoc;
this.bitvector[BYTE_SIZE - byteLoc - 1] = item;
}
}
/**
* Checks if an element is in the bloom.
* @param e - The element to check
* @throws {never}
*/
check(e) {
const eBytes = utils.hexToBytes(utils.keccak256(e));
const mask = 2047;
let match = true;
for (let i = 0; i < 3 && match; i++) {
const first2bytes = new DataView(eBytes.buffer).getUint16(i * 2);
const loc = mask & first2bytes;
const byteLoc = loc >> 3;
const bitLoc = 1 << loc % 8;
const item = this.bitvector[BYTE_SIZE - byteLoc - 1];
if (item === void 0) {
throw new errors.DefensiveNullCheckError("item is not defined. There is a bug in the implementation");
}
match = (item & bitLoc) !== 0;
}
return Boolean(match);
}
/**
* Checks if multiple topics are in a bloom.
* @returns `true` if every topic is in the bloom
* @throws {never}
*/
multiCheck(topics) {
return topics.every((t) => this.check(t));
}
/**
* Bitwise or blooms together.
* @throws {never}
*/
or(bloom) {
for (let i = 0; i <= BYTE_SIZE; i++) {
const a = this.bitvector[i];
const b = bloom.bitvector[i];
if (a === void 0) {
throw new errors.DefensiveNullCheckError("a is not defined. Please open an issue in the tevm github repo");
}
if (b === void 0) {
throw new errors.DefensiveNullCheckError("b is not defined. Please open an issue in the tevm github repo");
}
this.bitvector[i] = a | b;
}
}
};
var encodeKey = (bytes) => {
if (bytes instanceof Uint8Array) {
return utils.bytesToHex(bytes);
}
return bytes;
};
var createMemoryDb = (initialDb) => {
const db = initialDb ?? /* @__PURE__ */ new Map();
return {
get: (key) => {
return Promise.resolve(db.get(encodeKey(key)));
},
put: (key, value) => {
db.set(encodeKey(key), value);
return Promise.resolve();
},
del: (key) => {
db.delete(encodeKey(key));
return Promise.resolve();
},
shallowCopy: () => {
return createMemoryDb(new Map(db));
},
// For compatability
open: () => Promise.resolve(),
batch: (stack) => {
for (const item of stack) {
if (item.type === "del") {
db.delete(encodeKey(item.key));
} else if (item.type === "put") {
db.set(encodeKey(item.key), item.value);
} else {
return Promise.reject(new errors.UnreachableCodeError(item));
}
}
return Promise.resolve();
}
};
};
var PREFUNDED_PRIVATE_KEYS = [
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
// 0
"0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d",
// 1
"0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a",
// 2
"0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6",
// 3
"0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a",
// 4
"0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba",
// 5
"0x92db14e403b83dfe3df233f83dfa3a0d7096f21ca9b0d6d6b8d88b2b4ec1564e",
// 6
"0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356",
// 7
"0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97",
// 8
"0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6"
// 9
];
var PREFUNDED_PUBLIC_KEYS = [
"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
// 0
"0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
// 1
"0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC",
// 2
"0x90F79bf6EB2c4f870365E785982E1f101E93b906",
// 3
"0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65",
// 4
"0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc",
// 5
"0x976EA74026E726554dB657fA54763abd0C3a0aa9",
// 6
"0x14dC79964da2C08b23698B3D3cc7Ca32193d9955",
// 7
"0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f",
// 8
"0xa0Ee7A142d267C1f36714E4a8F75612F20a79720"
// 9
];
var PREFUNDED_ACCOUNTS = [
accounts.privateKeyToAccount(PREFUNDED_PRIVATE_KEYS[0]),
accounts.privateKeyToAccount(PREFUNDED_PRIVATE_KEYS[1]),
accounts.privateKeyToAccount(PREFUNDED_PRIVATE_KEYS[2]),
accounts.privateKeyToAccount(PREFUNDED_PRIVATE_KEYS[3]),
accounts.privateKeyToAccount(PREFUNDED_PRIVATE_KEYS[4]),
accounts.privateKeyToAccount(PREFUNDED_PRIVATE_KEYS[5]),
accounts.privateKeyToAccount(PREFUNDED_PRIVATE_KEYS[6]),
accounts.privateKeyToAccount(PREFUNDED_PRIVATE_KEYS[7]),
accounts.privateKeyToAccount(PREFUNDED_PRIVATE_KEYS[8]),
accounts.privateKeyToAccount(PREFUNDED_PRIVATE_KEYS[9])
];
var PREFUNDED_SEED = Object.freeze({
mnemonic: "test test test test test test test test test test test junk",
derivationPath: "m/44'/60'/0'/0/"
});
// src/signature.js
function recoverPublicKey({ hash, signature }) {
const v = signature.yParity !== void 0 ? signature.yParity : signature.v !== void 0 ? signature.v - 27 : (() => {
throw new Error("Either v or yParity must be provided in signature");
})();
const rBytes = new Uint8Array(32);
const sBytes = new Uint8Array(32);
const rBigInt = typeof signature.r === "string" ? BigInt(signature.r) : signature.r;
const sBigInt = typeof signature.s === "string" ? BigInt(signature.s) : signature.s;
for (let i = 0; i < 32; i++) {
rBytes[31 - i] = Number(rBigInt >> BigInt(8 * i) & 0xffn);
sBytes[31 - i] = Number(sBigInt >> BigInt(8 * i) & 0xffn);
}
const publicKey = util.ecrecover(utils.toBytes(hash), BigInt(v), rBytes, sBytes);
if (!publicKey) {
throw new Error("Failed to recover public key");
}
return `0x04${utils.toHex(publicKey).slice(2)}`;
}
function recoverAddress({ hash, signature }) {
const publicKey = recoverPublicKey({ hash, signature });
const publicKeyBytes = utils.toBytes(publicKey).slice(1);
const addressHash = utils.keccak256(publicKeyBytes);
return utils.getAddress(`0x${addressHash.slice(-40)}`);
}
function hashMessage(message) {
const prefix = `Ethereum Signed Message:
${message.length}`;
return utils.keccak256(utils.toBytes(prefix + message));
}
function recoverMessageAddress({ message, signature }) {
const hash = hashMessage(message);
return recoverAddress({ hash, signature });
}
function verifyMessage({ address, message, signature }) {
try {
const recoveredAddress = recoverMessageAddress({ message, signature });
return recoveredAddress.toLowerCase() === address.toLowerCase();
} catch {
return false;
}
}
async function signMessage({ privateKey, message }) {
const { signMessage: viemSignMessage } = await import('viem/accounts');
const signature = await viemSignMessage({ privateKey, message });
const v = Number.parseInt(signature.slice(130, 132), 16);
const yParity = (
/** @type {0 | 1} */
v - 27
);
return {
r: BigInt(signature.slice(0, 66)),
// First 32 bytes as hex
s: BigInt(`0x${signature.slice(66, 130)}`),
// Next 32 bytes as hex
v,
// Already 27/28
yParity
};
}
function invariant(condition, error = new errors.DefensiveNullCheckError()) {
if (!condition) {
throw error;
}
}
Object.defineProperty(exports, "formatAbi", {
enumerable: true,
get: function () { return abitype.formatAbi; }
});
Object.defineProperty(exports, "parseAbi", {
enumerable: true,
get: function () { return abitype.parseAbi; }
});
Object.defineProperty(exports, "mnemonicToAccount", {
enumerable: true,
get: function () { return accounts.mnemonicToAccount; }
});
Object.defineProperty(exports, "boolToBytes", {
enumerable: true,
get: function () { return utils.boolToBytes; }
});
Object.defineProperty(exports, "boolToHex", {
enumerable: true,
get: function () { return utils.boolToHex; }
});
Object.defineProperty(exports, "bytesToBigInt", {
enumerable: true,
get: function () { return utils.bytesToBigInt; }
});
Object.defineProperty(exports, "bytesToBigint", {
enumerable: true,
get: function () { return utils.bytesToBigint; }
});
Object.defineProperty(exports, "bytesToBool", {
enumerable: true,
get: function () { return utils.bytesToBool; }
});
Object.defineProperty(exports, "bytesToHex", {
enumerable: true,
get: function () { return utils.bytesToHex; }
});
Object.defineProperty(exports, "bytesToNumber", {
enumerable: true,
get: function () { return utils.bytesToNumber; }
});
Object.defineProperty(exports, "decodeAbiParameters", {
enumerable: true,
get: function () { return utils.decodeAbiParameters; }
});
Object.defineProperty(exports, "decodeErrorResult", {
enumerable: true,
get: function () { return utils.decodeErrorResult; }
});
Object.defineProperty(exports, "decodeEventLog", {
enumerable: true,
get: function () { return utils.decodeEventLog; }
});
Object.defineProperty(exports, "decodeFunctionData", {
enumerable: true,
get: function () { return utils.decodeFunctionData; }
});
Object.defineProperty(exports, "decodeFunctionResult", {
enumerable: true,
get: function () { return utils.decodeFunctionResult; }
});
Object.defineProperty(exports, "encodeAbiParameters", {
enumerable: true,
get: function () { return utils.encodeAbiParameters; }
});
Object.defineProperty(exports, "encodeDeployData", {
enumerable: true,
get: function () { return utils.encodeDeployData; }
});
Object.defineProperty(exports, "encodeErrorResult", {
enumerable: true,
get: function () { return utils.encodeErrorResult; }
});
Object.defineProperty(exports, "encodeEventTopics", {
enumerable: true,
get: function () { return utils.encodeEventTopics; }
});
Object.defineProperty(exports, "encodeFunctionData", {
enumerable: true,
get: function () { return utils.encodeFunctionData; }
});
Object.defineProperty(exports, "encodeFunctionResult", {
enumerable: true,
get: function () { return utils.encodeFunctionResult; }
});
Object.defineProperty(exports, "encodePacked", {
enumerable: true,
get: function () { return utils.encodePacked; }
});
Object.defineProperty(exports, "formatEther", {
enumerable: true,
get: function () { return utils.formatEther; }
});
Object.defineProperty(exports, "formatGwei", {
enumerable: true,
get: function () { return utils.formatGwei; }
});
Object.defineProperty(exports, "formatLog", {
enumerable: true,
get: function () { return utils.formatLog; }
});
Object.defineProperty(exports, "fromBytes", {
enumerable: true,
get: function () { return utils.fromBytes; }
});
Object.defineProperty(exports, "fromHex", {
enumerable: true,
get: function () { return utils.fromHex; }
});
Object.defineProperty(exports, "fromRlp", {
enumerable: true,
get: function () { return utils.fromRlp; }
});
Object.defineProperty(exports, "getAddress", {
enumerable: true,
get: function () { return utils.getAddress; }
});
Object.defineProperty(exports, "hexToBigInt", {
enumerable: true,
get: function () { return utils.hexToBigInt; }
});
Object.defineProperty(exports, "hexToBool", {
enumerable: true,
get: function () { return utils.hexToBool; }
});
Object.defineProperty(exports, "hexToBytes", {
enumerable: true,
get: function () { return utils.hexToBytes; }
});
Object.defineProperty(exports, "hexToNumber", {
enumerable: true,
get: function () { return utils.hexToNumber; }
});
Object.defineProperty(exports, "hexToString", {
enumerable: true,
get: function () { return utils.hexToString; }
});
Object.defineProperty(exports, "isAddress", {
enumerable: true,
get: function () { return utils.isAddress; }
});
Object.defineProperty(exports, "isBytes", {
enumerable: true,
get: function () { return utils.isBytes; }
});
Object.defineProperty(exports, "isHex", {
enumerable: true,
get: function () { return utils.isHex; }
});
Object.defineProperty(exports, "keccak256", {
enumerable: true,
get: function () { return utils.keccak256; }
});
Object.defineProperty(exports, "numberToHex", {
enumerable: true,
get: function () { return utils.numberToHex; }
});
Object.defineProperty(exports, "parseEther", {
enumerable: true,
get: function () { return utils.parseEther; }
});
Object.defineProperty(exports, "parseGwei", {
enumerable: true,
get: function () { return utils.parseGwei; }
});
Object.defineProperty(exports, "serializeTransaction", {
enumerable: true,
get: function () { return utils.serializeTransaction; }
});
Object.defineProperty(exports, "stringToHex", {
enumerable: true,
get: function () { return utils.stringToHex; }
});
Object.defineProperty(exports, "toBytes", {
enumerable: true,
get: function () { return utils.toBytes; }
});
Object.defineProperty(exports, "toHex", {
enumerable: true,
get: function () { return utils.toHex; }
});
Object.defineProperty(exports, "toRlp", {
enumerable: true,
get: function () { return utils.toRlp; }
});
Object.defineProperty(exports, "EthjsAccount", {
enumerable: true,
get: function () { return util.Account; }
});
Object.defineProperty(exports, "EthjsAddress", {
enumerable: true,
get: function () { return util.Address; }
});
Object.defineProperty(exports, "GWEI_TO_WEI", {
enumerable: true,
get: function () { return util.GWEI_TO_WEI; }
});
Object.defineProperty(exports, "KECCAK256_RLP", {
enumerable: true,
get: function () { return util.KECCAK256_RLP; }
});
Object.defineProperty(exports, "KECCAK256_RLP_ARRAY", {
enumerable: true,
get: function () { return util.KECCAK256_RLP_ARRAY; }
});
Object.defineProperty(exports, "KeyEncoding", {
enumerable: true,
get: function () { return util.KeyEncoding; }
});
Object.defineProperty(exports, "TypeOutput", {
enumerable: true,
get: function () { return util.TypeOutput; }
});
Object.defineProperty(exports, "ValueEncoding", {
enumerable: true,
get: function () { return util.ValueEncoding; }
});
Object.defineProperty(exports, "Withdrawal", {
enumerable: true,
get: function () { return util.Withdrawal; }
});
Object.defineProperty(exports, "bytesToUnprefixedHex", {
enumerable: true,
get: function () { return util.bytesToUnprefixedHex; }
});
Object.defineProperty(exports, "bytesToUtf8", {
enumerable: true,
get: function () { return util.bytesToUtf8; }
});
Object.defineProperty(exports, "concatBytes", {
enumerable: true,
get: function () { return util.concatBytes; }
});
Object.defineProperty(exports, "createAccount", {
enumerable: true,
get: function () { return util.createAccount; }
});
Object.defineProperty(exports, "createAddressFromString", {
enumerable: true,
get: function () { return util.createAddressFromString; }
});
Object.defineProperty(exports, "createWithdrawal", {
enumerable: true,
get: function () { return util.createWithdrawal; }
});
Object.defineProperty(exports, "ecrecover", {
enumerable: true,
get: function () { return util.ecrecover; }
});
Object.defineProperty(exports, "equalsBytes", {
enumerable: true,
get: function () { return util.equalsBytes; }
});
Object.defineProperty(exports, "fetchFromProvider", {
enumerable: true,
get: function () { return util.fetchFromProvider; }
});
Object.defineProperty(exports, "getProvider", {
enumerable: true,
get: function () { return util.getProvider; }
});
Object.defineProperty(exports, "randomBytes", {
enumerable: true,
get: function () { return util.randomBytes; }
});
Object.defineProperty(exports, "setLengthLeft", {
enumerable: true,
get: function () { return util.setLengthLeft; }
});
Object.defineProperty(exports, "toType", {
enumerable: true,
get: function () { return util.toType; }
});
exports.Bloom = Bloom;
exports.PREFUNDED_ACCOUNTS = PREFUNDED_ACCOUNTS;
exports.PREFUNDED_PRIVATE_KEYS = PREFUNDED_PRIVATE_KEYS;
exports.PREFUNDED_PUBLIC_KEYS = PREFUNDED_PUBLIC_KEYS;
exports.PREFUNDED_SEED = PREFUNDED_SEED;
exports.createMemoryDb = createMemoryDb;
exports.hashMessage = hashMessage;
exports.invariant = invariant;
exports.recoverAddress = recoverAddress;
exports.recoverMessageAddress = recoverMessageAddress;
exports.recoverPublicKey = recoverPublicKey;
exports.signMessage = signMessage;
exports.verifyMessage = verifyMessage;
//# sourceMappingURL=index.cjs.map
//# sourceMappingURL=index.cjs.map