├── 01-工具类 └── 01-顺序钱包生成 │ ├── BulkVanityAddress.js │ └── package.json └── 02-脚本 └── 01-Tabi领水 ├── getTabiToken.js ├── package.json └── seeds.txt /01-工具类/01-顺序钱包生成/BulkVanityAddress.js: -------------------------------------------------------------------------------- 1 | import { ethers } from "ethers"; 2 | import fs from "fs/promises"; 3 | 4 | 5 | // 生成钱包,传入regexList数组并进行匹配,如匹配到则从数组中删除对应regex 6 | async function CreateWallet(regexList) { 7 | let wallet; 8 | var isValid = false; 9 | 10 | //从21讲的代码扩充 11 | //https://github.com/WTFAcademy/WTFEthers/blob/main/21_VanityAddress/readme.md 12 | while (!isValid && regexList.length > 0) { 13 | wallet = ethers.Wallet.createRandom(); 14 | const index = regexList.findIndex(regex => regex.test(wallet.address)); 15 | // 移除匹配的正则表达式 16 | if (index !== -1) { 17 | isValid = true; 18 | regexList.splice(index, 1); 19 | } 20 | } 21 | const data = `${wallet.address}:${wallet.privateKey}` 22 | console.log(data); 23 | return data 24 | } 25 | 26 | // 生成正则匹配表达式,并返回数组 27 | function CreateRegex(total) { 28 | const regexList = []; 29 | for (let index = 0; index < total; index++) { 30 | // 填充3位数字,比如001,002,003,...,999 31 | const paddedIndex = (index + 1).toString().padStart(3, '0'); 32 | const regex = new RegExp(`^0x${paddedIndex}.*$`); 33 | regexList.push(regex); 34 | } 35 | return regexList; 36 | } 37 | 38 | // 需要生成的钱包数量 39 | const total = 10; 40 | 41 | // 生成正则表达式 42 | const regexL = CreateRegex(total) 43 | // 数组存储生成地址 44 | const privateKeys = [] 45 | 46 | 47 | for (let index = 1; index < total + 1; index++) { 48 | privateKeys.push(await CreateWallet(regexL)) 49 | } 50 | 51 | // 异步写入seeds.txt,因顺序生成钱包地址前三位,使用自带sort()函数即可排序,并在每个地址后添加换行符保存 52 | await fs.appendFile('seeds.txt', privateKeys.sort().join('\n')); -------------------------------------------------------------------------------- /01-工具类/01-顺序钱包生成/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "ethers": "^6.11.1" 4 | }, 5 | "type": "module" 6 | } 7 | -------------------------------------------------------------------------------- /02-脚本/01-Tabi领水/getTabiToken.js: -------------------------------------------------------------------------------- 1 | const axios = require('axios'); 2 | const fss = require('fs/promises'); 3 | const fs = require('fs'); 4 | //import fs from "fs/promises"; 5 | const csv = require('csv-parser'); 6 | //const config = require('../../config/runner.json'); 7 | const { HttpsProxyAgent } = require('https-proxy-agent'); 8 | const fakeUa = require('fake-useragent'); 9 | const userAgent = fakeUa(); 10 | 11 | const MAX_RETRIES = 5; // 最大重试次数 12 | const MAX_PROXY_CHECK_ATTEMPTS = 3; 13 | const Proxy = 'http://1gnXXXX7m:Ce4XXXXXi4V@proxy.proxy-cheap.com:31112' 14 | 15 | const agent = new HttpsProxyAgent(Proxy); 16 | 17 | async function processAddresses(filePath) { 18 | try { 19 | const ADDRESS = await fss.readFile(filePath, 'utf8'); 20 | 21 | // 使用 split('\n') 替代正则表达式来拆分行 22 | const lines = ADDRESS.split(/\r?\n|\r/g); 23 | 24 | // 如果最后一行是空行,则去掉 25 | if (lines[lines.length - 1].trim() === '') { 26 | lines.pop(); 27 | } 28 | 29 | const addList = lines.map((line) => { 30 | // 使用 split(':') 来获取冒号前的部分 31 | return line.split(':')[0]//.trim(); 32 | }); 33 | 34 | console.log(addList); 35 | return addList 36 | 37 | } catch (err) { 38 | console.error('读取文件时出错:', err); 39 | } 40 | } 41 | 42 | async function verifyProxy(agent) { 43 | for (let attempt = 1; attempt <= MAX_PROXY_CHECK_ATTEMPTS; attempt++) { 44 | try { 45 | await axios.get('https://myip.ipip.net', { httpsAgent: agent }); 46 | console.log('代理验证成功'); 47 | return true; 48 | } catch (error) { 49 | console.log(`代理验证失败,尝试次数:${attempt}`); 50 | if (attempt < MAX_PROXY_CHECK_ATTEMPTS) await sleep(60000); // 等待1分钟 51 | } 52 | } 53 | return false; 54 | } 55 | //verifyProxy() 56 | async function main() { 57 | try { 58 | const addresses = await processAddresses('seeds.txt'); 59 | // console.log(typeof addresses); 60 | // console.log(addresses); 61 | console.log('开始领取测试币'); 62 | 63 | const userAgent = fakeUa(); 64 | const agent = new HttpsProxyAgent(Proxy); 65 | const headers = { 66 | 'accept': '*/*', 67 | 'Accept-Encoding': 'gzip, deflate, br', 68 | 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8', 69 | 'content-type': 'application/json', 70 | 'origin': 'https://faucet.testnet.tabichain.com', 71 | 'referer': 'https://faucet.testnet.tabichain.com/', 72 | 'user-agent': userAgent, 73 | }; 74 | 75 | if (!(await verifyProxy(agent))) { 76 | console.log('代理验证失败,无法继续执行任务'); 77 | return; 78 | } 79 | 80 | for (const address of addresses) { 81 | console.log(`领取地址: ${address}`); 82 | 83 | for (let attempts = 0; attempts < MAX_RETRIES; attempts++) { 84 | try { 85 | const url = `https://faucet-api.testnet.tabichain.com/api/faucet`; 86 | const data = { address: address }; 87 | const response = await axios.post(url, data, { 88 | headers: headers, 89 | httpsAgent: agent, 90 | }); 91 | console.log('领取成功✅ ', response.data.message); 92 | await sleep(3000); // 等待3秒 93 | break; 94 | } catch (error) { 95 | console.error(`领取失败❌,地址:${address}: ${error.message}`); 96 | if (attempts === MAX_RETRIES - 1) console.log('达到最大重试次数,继续下一个地址'); 97 | else await sleep(10000); // 等待10秒后重试 98 | } 99 | } 100 | } 101 | } catch (error) { 102 | console.error('发生错误:', error); 103 | } 104 | } 105 | 106 | function sleep(ms) { 107 | return new Promise(resolve => setTimeout(resolve, ms)); 108 | } 109 | 110 | main() -------------------------------------------------------------------------------- /02-脚本/01-Tabi领水/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "robots", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "claimRaffle.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "axios": "^1.6.7", 13 | "child_process": "^1.0.2", 14 | "csv-parser": "^3.0.0", 15 | "csv-writer": "^1.6.0", 16 | "ethers": "^5.7.2", 17 | "fake-useragent": "^1.0.1", 18 | "fs": "^0.0.1-security", 19 | "https-proxy-agent": "^7.0.2", 20 | "node-fetch": "^2.7.0", 21 | "readline-sync": "^1.4.10", 22 | "save": "^2.9.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /02-脚本/01-Tabi领水/seeds.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/b1n4he/AirdropTools/00a9f90ad24cc78e34b4579e76df138b74a33b38/02-脚本/01-Tabi领水/seeds.txt --------------------------------------------------------------------------------