Closed3
【16倍高速化】ethers.jsで高速にランダムなアドレスを大量に生成するTips
ピン留めされたアイテム
Xでもっといいアイデアを頂いたので掲載させていただく。
araさんありがとうございました!
自分のは秘密鍵も欲しくなったら、同等の速度で動くはず。
❯ yarn generateAddresses
yarn run v1.22.19
$ tsx scripts/generateAddresses.ts
10000 個のアドレスが addresses.csv ファイルに保存されました。
✨ Done in 0.22s.
早すぎる!
テスト用にアドレスを大量に作りたい
2023/10/28現在、GPT4にethers.jsでアドレスを大量に生成したいっていうと、次のようなコードを吐いてくる。
import { Wallet } from 'ethers';
import * as fs from 'fs';
const generateAddresses = async (): Promise<void> => {
let csvContent = 'address\n'; // CSV Header
for (let i = 0; i < 10000; i++) {
const wallet = Wallet.createRandom();
csvContent += `${wallet.address}\n`;
}
// Write to CSV file
fs.writeFile('addresses.csv', csvContent, (err) => {
if (err) {
console.error('エラーが発生:', err);
} else {
console.log('10,000 個のアドレスが addresses.csv ファイルに保存されました。');
}
});
};
generateAddresses();
実行してみる
❯ yarn generateAddresses
yarn run v1.22.19
$ tsx scripts/generateAddresses.ts
10,000 個のアドレスが addresses.csv ファイルに保存されました。
✨ Done in 96.70s.
間違いではないけど、ただアドレスが1万個欲しいにしてはやりすぎだし、遅すぎる。
手元のM1 Macで実行すると90秒近くかかる。
ちゃんとベンチ取ったわけじゃないけど、csprng(暗号論的擬似乱数生成器)で何個も生成するのが遅いんだと思う。
高速化する
何個もseedを生成する必要は今回のユースケースにおいて全く必要なく、HDNodeをDeriveしていくだけでいい。
import {Wallet} from 'ethers';
import {HDNode} from 'ethers/lib/utils';
import {promises as fs} from 'fs';
const generateAddresses = async (): Promise<void> => {
// ランダムなウォレットとその mnemonic を生成
const masterWallet = Wallet.createRandom();
const masterNode = HDNode.fromMnemonic(masterWallet.mnemonic.phrase);
const numAddresses = 10000;
const addresses = [];
// 基本のパスを設定
const baseNode = masterNode.derivePath("m/44'/60'/0'/0");
for (let i = 0; i < numAddresses; i++) {
const derivedNode = baseNode.derivePath(String(i));
addresses.push(derivedNode.address);
}
// CSV形式に変換
const csvContent = `address\n${addresses.join('\n')}\n`;
// ファイルに書き込み
await fs.writeFile('addresses.csv', csvContent);
console.log(
`${numAddresses} 個のアドレスが addresses.csv ファイルに保存されました。`
);
};
generateAddresses().catch(err => {
console.error('エラーが発生:', err);
});
実行してみる
❯ yarn generateAddresses
yarn run v1.22.19
$ tsx scripts/generateAddresses.ts
10000 個のアドレスが addresses.csv ファイルに保存されました。
✨ Done in 6.34s.
やったぜ!!16倍もの高速化に成功した🚀🚀🚀
もっと高速化しようと思うと、そもそもJSを使わないとか、viem使うとかそういうアイデアになってきそう。
↓下でviemも試してみました。viemは早いというイメージがありましたが、ethers.js高速化の3倍以上遅いです。
他にいいやり方あればツッコミお願いします!
viemも試してみた
import {promises as fs} from 'fs';
import {
hdKeyToAccount,
generateMnemonic,
english,
mnemonicToAccount,
} from 'viem/accounts';
const generateAddresses = async (): Promise<void> => {
const mnemonic = generateMnemonic(english);
const account = mnemonicToAccount(mnemonic);
const baseHDKey = account.getHdKey();
const numAddresses = 10000;
const addresses = [];
for (let i = 0; i < numAddresses; i++) {
const derivedHDKey = baseHDKey.deriveChild(i);
const account = hdKeyToAccount(derivedHDKey);
addresses.push(account.address);
}
// CSV形式に変換
const csvContent = `address\n${addresses.join('\n')}\n`;
// ファイルに書き込み
await fs.writeFile('addresses.csv', csvContent);
console.log(
`${numAddresses} 個のアドレスが addresses.csv ファイルに保存されました。`
);
};
generateAddresses().catch(err => {
console.error('エラーが発生:', err);
});
実行!!
❯ yarn generateAddresses
yarn run v1.22.19
$ tsx scripts/generateAddresses.ts
10000 個のアドレスが addresses.csv ファイルに保存されました。
✨ Done in 19.43s.
!!!!!!!!!!!!
まさかのviemの方が遅いです
このスクラップは2023/10/28にクローズされました