如何调整嵌套循环实现钱包与代币按顺序一一对应转账空投
一一对应代币空投脚本修正方案
问题核心
你当前使用的双层嵌套循环会遍历两个列表的所有组合,也就是如果钱包列表有100条、代币列表有100条,代码会执行100*100=10000次转账逻辑,完全不符合一一对应的要求,才会出现大量重复无效操作。
你需要的钱包N对应代币N的逻辑,根本不需要嵌套循环,单循环按索引配对就能实现。
修正步骤
- 先校验两个列表的长度是否一致,长度不匹配直接抛错,避免出现钱包/代币数量对不上的错转问题
- 删掉内层for循环,单次遍历钱包列表,直接取相同索引的代币地址配对即可
- 修正已处理条目的判断逻辑:当前索引对应的钱包或代币任意一个带
(sent)标记就跳过,不用等两个都标记 - 修复原代码里错误提示的语法错误(原代码错误信息里漏了一个左方括号)
- 增加空行过滤逻辑,避免TXT文件首尾、中间的空行被识别为有效地址
修正后完整代码
const shell = require("shelljs"); const fs = require("fs"); const numberToAirdrop = 1; const pathToTheWLFile = "./wl.txt" // 钱包地址列表 const pathToTheTKFile = "./tk.txt" // 代币地址列表 const wlFile = fs.readFileSync(pathToTheWLFile).toString().replace(/\r/g, '').split("\n").filter(line => line.trim() !== ''); const tkFile = fs.readFileSync(pathToTheTKFile).toString().replace(/\r/g, '').split("\n").filter(line => line.trim() !== ''); // 提前校验两个列表长度匹配 if (wlFile.length !== tkFile.length) { throw new Error(`钱包列表长度(${wlFile.length})和代币列表长度(${tkFile.length})不匹配,无法一一对应转账,请检查文件内容`) } console.log("钱包列表:", wlFile) console.log("代币列表:", tkFile) // 单循环按索引一一配对,不需要嵌套 for (const [index, address] of wlFile.entries()) { const matchToken = tkFile[index]; // 只要当前钱包或代币已经处理过就跳过 if (address.includes("(sent) ") || matchToken.includes("(sent) ")) { console.log(`[${index}] 跳过已处理条目:钱包 ${address} ,代币 ${matchToken}`); continue; } console.log(`[${index}] 正在向钱包 ${address} 转账 ${numberToAirdrop} 个代币 ${matchToken}`); console.time("转账耗时") const output = shell.exec(`spl-token transfer ${matchToken} ${numberToAirdrop} ${address} --allow-unfunded-recipient --fund-recipient -v`); if (output.stderr && output.code !== 0) { throw new Error( `[${index}] 向钱包 ${address} 转代币 ${matchToken} 失败,上次处理到的条目:${"(sent) to" + wlFile[index] + tkFile[index]}` ) } // 标记已处理 tkFile[index] = "(sent) " + tkFile[index] wlFile[index] = "(sent) " + wlFile[index] fs.writeFileSync(pathToTheWLFile, wlFile.join("\n")); fs.writeFileSync(pathToTheTKFile, tkFile.join("\n")); console.log(`[${index}] 向钱包 ${address} 转账 ${numberToAirdrop} 个代币 ${matchToken} 成功\n\n`); console.timeEnd("转账耗时") } const notDone = wlFile.find((i) => !i.includes("(sent)")); if (notDone) { console.log("未完成所有地址的转账,请重新运行脚本") return; } console.log("转账完成!所有代币已成功空投!")
补充说明
如果你非要保留嵌套循环的写法也可以实现,只要在内层循环开头加判断if (index !== index2) continue,但这种写法完全是多此一举,性能差还容易出逻辑漏洞,非常不推荐。
内容的提问来源于stack exchange,提问作者dev
相关产品推荐
相关产品推荐

