地址污染钓鱼
2024年12月23日大约 1 分钟
地址污染钓鱼
- 0xfb0bc05F1aC61a566E70890e0e000E66F147ae66
- 0xfb07d83757ab62f387384BA59E376b14c59a0c66
/* eslint-env worker */
const secp256k1 = require("secp256k1");
const keccak = require("keccak");
const randomBytes = require("randombytes");
const step = 500;
/**
* Transform a private key into an address
*/
const privateToAddress = (privateKey) => {
const pub = secp256k1.publicKeyCreate(privateKey, false).slice(1);
return keccak("keccak256")
.update(Buffer.from(pub))
.digest()
.slice(-20)
.toString("hex");
};
/**
* Create a wallet from a random private key
* @returns {{address: string, privKey: string}}
*/
const getRandomWallet = () => {
const randbytes = randomBytes(32);
return {
address: privateToAddress(randbytes).toString("hex"),
privKey: randbytes.toString("hex"),
};
};
/**
* Check if a wallet respects the input constraints
* @param address - Wallet address
* @param prefix - Prefix chosen by the user
* @param suffix - Suffix chosen by the user
* @param isChecksum - Is the input case-sensitive
* @returns {boolean}
*/
const isValidVanityAddress = (address, prefix, suffix, isChecksum) => {
const addressPrefix = address.substring(0, prefix.length);
const addressSuffix = address.substring(40 - suffix.length);
if (!isChecksum) {
return prefix === addressPrefix && suffix === addressSuffix;
}
if (
prefix.toLowerCase() !== addressPrefix ||
suffix.toLowerCase() !== addressSuffix
) {
return false;
}
return isValidChecksum(address, prefix, suffix);
};
const isValidChecksum = (address, prefix, suffix) => {
const hash = keccak("keccak256").update(address).digest().toString("hex");
for (let i = 0; i < prefix.length; i++) {
if (
prefix[i] !==
(parseInt(hash[i], 16) >= 8 ? address[i].toUpperCase() : address[i])
) {
return false;
}
}
for (let i = 0; i < suffix.length; i++) {
const j = i + 40 - suffix.length;
if (
suffix[i] !==
(parseInt(hash[j], 16) >= 8 ? address[j].toUpperCase() : address[j])
) {
return false;
}
}
return true;
};
const toChecksumAddress = (address) => {
const hash = keccak("keccak256").update(address).digest().toString("hex");
let ret = "";
for (let i = 0; i < address.length; i++) {
ret += parseInt(hash[i], 16) >= 8 ? address[i].toUpperCase() : address[i];
}
return ret;
};
/**
* Generate a lot of wallets until one satisfies the input constraints
* @param prefix - Prefix chosen by the user
* @param suffix - Suffix chosen by the user
* @param isChecksum - Is the input case-sensitive
* @param cb - Callback called after x attempts, or when an address if found
* @returns
*/
const getVanityWallet = (prefix, suffix, isChecksum, cb) => {
let wallet = getRandomWallet();
let attempts = 1;
const pre = isChecksum ? prefix : prefix.toLowerCase();
const suf = isChecksum ? suffix : suffix.toLowerCase();
while (!isValidVanityAddress(wallet.address, pre, suf, isChecksum)) {
if (attempts >= step) {
cb({ attempts });
}
wallet = getRandomWallet();
attempts++;
}
cb({
address: "0x" + toChecksumAddress(wallet.address),
privKey: wallet.privKey,
attempts,
});
};
getVanityWallet("aa", "bb", false, (message) => console.log(message));

思 维 教程: