本文详细介绍了如何使用 JavaScript 编写一个自动交易机器人,以便在 PancakeSwap 上购买新发行的代币。文章涵盖了必要的前提条件、PancakeSwap 的基础知识、节点设置、代码编写以及最终实现自动购买的逻辑。读者在完成此指南后将对构建交易机器人有一个全面的理解,并能够在 BSC 网络上进行交易。
你好,读者!今天我们将深入探讨如何创建一个在 PancakeSwap DEX 上购买新发行代币的机器人。今天可能是你第一次制作交易机器人或使用 BSC 网络,这没关系!当你阅读并完成本指南时,你将拥有一个 BNB 智能链节点,连接的钱包和交易机器人,以便在 PancakeSwap DEX 上发起交易!
先决条件:
PancakeSwap 是一个去中心化交易所(DEX)。如果你用传统金融的术语来想,PancakeSwap 就像一个你可以买卖商品的市场。PancakeSwap 基于 BNB 智能链 之上,这意味着与以太坊 DEX 相比,交易发生得稍微快一些,Gas费也稍微低一些。你可以将 PancakeSwap 与 SushiSwap 或 UniSwap 进行比较,尽管它们都是在以太坊上。
够了历史课。你来这里是为了购买一些刚刚发行的代币,对吗?首先,我想警告你,我们正在编码的这个购买新代币的机器人只是一个概念验证。虽然你_理论上_可以从中获利,但我强烈建议你根据自己的风险承受能力进行自定义修改。这样才能为你提供构建更智能机器人的工具。
这个机器人的核心依赖于监听区块链上发出的特定事件。在这种情况下,我们正在监听 PancakeSwap 上新代币的创建。
在你过于兴奋之前,我们需要配置好工具以便与 PancakeSwap 一起使用。在这里,工具指的是我们的钱包和连接到 BSC 网络的节点。在今天的指南中,我使用的是配对 QuickNode 的 MetaMask 钱包与 BSC 节点。
虽然这个目标可以通过连接任何 BSC 网络的节点来实现,但在 QuickNode,我们使设置具备 WebSocket 功能的 BSC 节点变得快速而简单。这在教程的后面会派上用场,因为我们希望能够监听信息流。
你可以注册适合你需求的任何计划,然后确保在 BSC 主网下启动你的节点。
你可以在 这里 注册并申请一个免费账户。
你将需要本教程所需的 HTTPS 和 WSS 端点。它应该看起来像这样:
节点成功设置后,我们现在需要将 MetaMask 连接到这个新网络。打开扩展程序后,扩展网络选项卡,点击 "Custom RPC"。你将根据这张图片准确填写,除了在 "New RPC URL" 字段下复制你的 QuickNode HTTPS 端点。
干得好!现在你可以在 BSC 网络上使用你的钱包了。所有配置正确后,我们可以开始编码机器人了!
首先,你需要为机器人的代码设置一个目录。
mkdir PancakeSwapBot
cd PancakeSwapBot
完成后,在你的目录中创建一个 bot.js 文件。
在开始编码之前,我们需要添加 ethers 包。这个库允许我们使用 JavaScript 与区块链进行交互。确保安装 5.7 版本。要安装它,在项目根目录下运行以下命令:
npm i ethers@5.7
继续打开你选择的文本编辑器中的 bot.js 文件。然后在顶部添加以下代码:
const ethers = require('ethers');
const addresses = {
WBNB: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",
router: "0x10ED43C718714eb63d5aA57B78B54704E256024E",
factory: "0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73",
me: "YOUR_WALLET_ADDRESS"
}
const mnemonic = "orange banana apple bravo charlie delta gamma ........."
const provider = new ethers.providers.WebSocketProvider("QUICKNODE_WSS_PROVIDER_HERE")
const wallet = ethers.Wallet.fromMnemonic(mnemonic);
const account = wallet.connect(provider)
我们逐行来分析一下。
第 1 行:导入我们之前安装的 ether 库。
第 3-8 行:列出我们需要完成脚本的所有地址。
第 10 行:mnemonic 是你钱包的助记词。你可以从 MetaMask 获取这个词。确保不要与任何人分享或将其放在公共库中。任何拥有这个助记词的人都可以访问和控制你的钱包!
第 12-14 行:provider,wallet 和 account 是允许你从程序连接到 QuickNode Websocket 提供者并将你的钱包挂接到其他内容的变量。这一部分是你项目的粘合剂。
在处理完所有地址后,我们需要定义将要使用的两个合约。
const factory = new ethers.Contract(
addresses.factory,
['event PairCreated(address indexed token0, address indexed token1, address pair, uint)'],
account
);
const router = new ethers.Contract(
addresses.router,
[\
'function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts)',\
'function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)',\
],
account
);
在这里,我们使用 ether 的 Contract 方法初始化两个不同的合约。要创建一个新的 Contract,你需要传入智能合约的地址、你希望在数组中使用的 ABI 部分以及一个钱包。想了解更多关于 ABI 的信息,你可以阅读我们的 指南。
我将只分析 factory,因为两者的格式是一样的。
第 1 行:调用 ethers.Contract 方法。
第 2 行:传入 PancakeSwap Factory 合约的地址。
第 3 行:传递为新在 PancakeSwap 创建的每对代币产生的 PairCreated 事件 ABI。你可以在 这 找到整个合约的 ABI。
第 4 行:传入 account 变量,这就是允许合约访问我们钱包的内容。
如果你想查看 router 的 ABI,你可以在 这里 找到。这是一个很好的熟悉 Solidity 代码的方式。它可能还会给你一些其他你不会有的想法!
初始化这两个合约后,我们现在可以在 JavaScript 代码中使用 ABI 中定义的功能。下一步就是魔法发生的地方!
在开始编码之前,考虑一下我们需要做些什么。我们有当新代币在 PancakeSwap 上发行时发出的事件。在我们的情况下,我们想买一点我们的代币。考虑到这一点,我们的计划大致如下:
监听事件
找出哪个代币是哪个
使用我们的 WBNB 购买一些新代币
确保汇率接近我们被报价的价格
将新代币发送到我们的钱包
有了这张路线图,你应该能更好地跟动力所在。是时候跳入代码了!
factory.on("PairCreated", async (token0, token1, addressPair) => {
console.log(`
~~~~~~~~~~~~~~~~~~
新的交易对被检测到
~~~~~~~~~~~~~~~~~~
token0: ${token0}
token1: ${token1}
addressPair: ${addressPair}
`);
// 此块确保我们使用 WBNB 进行支付
let buyToken, sellToken;
if(token0 === addresses.WBNB) {
buyToken = token0;
sellToken = token1;
}
if (token1 === addresses.WBNB) {
buyToken = token1;
sellToken = token0;
}
// 两个代币都不是 WBNB,我们无法购买
if(typeof buyToken === "undefined") {
return
}
const amountIn = ethers.utils.parseUnits('0.1', 'ether'); //ether 是测量单位,不是币
const amounts = await router.getAmountsOut(amountIn, [buyToken, sellToken]);
const amountOutMin = amounts[1].sub(amounts[1].div(10)); // JS 中大数的数学运算
console.log(`
~~~~~~~~~~~~~~~~~~~~
正在购买新代币
~~~~~~~~~~~~~~~~~~~~
buyToken: ${amountIn.toString()} ${buyToken} (WBNB)
sellToken: ${amountOutMin.toString()} ${sellToken}
`);
const tx = await router.swapExactTokensForTokens(
amountIn,
amountOutMin,
[buyToken, sellToken],
addresses.me,
Date.now() + 1000 * 60 * 5 //5分钟
);
const receipt = await tx.wait();
console.log('交易收据');
console.log(receipt);
}
)
这段代码块有点大,所以我们将其分解为更小的部分,从顶部开始。
factory.on("PairCreated", async (token0, token1, addressPair) => {
console.log(`
~~~~~~~~~~~~~~~~~~
新的交易对被检测到
~~~~~~~~~~~~~~~~~~
token0: ${token0}
token1: ${token1}
addressPair: ${addressPair}
`);
第 1 行:在 factory 的 PairCreated 方法上设置监听器,每次触发时将调用此 async lambda 函数。
第 2-9 行:打印出与 factory 的 ABI 的 PairCreated 给定的参数映射的 token0、token1 和 addressPair。
// 此块确保我们使用 WBNB 进行支付
let buyToken, sellToken;
if(token0 === addresses.WBNB) {
buyToken = token0;
sellToken = token1;
}
if (token1 === addresses.WBNB) {
buyToken = token1;
sellToken = token0;
}
// 两个代币都不是 WBNB,我们无法购买
if(typeof buyToken === "undefined") {
return
}
const amountIn = ethers.utils.parseUnits('0.1', 'ether'); //ether 是测量单位,不是币
const amounts = await router.getAmountsOut(amountIn, [buyToken, sellToken]);
const amountOutMin = amounts[1].sub(amounts[1].div(10)); // JS 中大数的数学运算
console.log(`
~~~~~~~~~~~~~~~~~~~~
正在购买新代币
~~~~~~~~~~~~~~~~~~~~
buyToken: ${amountIn.toString()} ${buyToken} (WBNB)
sellToken: ${amountOutMin.toString()} ${sellToken}
`);
这就是那段代码的全部内容。接下来是最后一段代码!
const tx = await router.swapExactTokensForTokens(
amountIn,
amountOutMin,
[buyToken, sellToken],
addresses.me,
Date.now() + 1000 * 60 * 5 //5分钟
);
const receipt = await tx.wait();
console.log('交易收据');
console.log(receipt);
}
)
我们调用在 router 中定义的第二个合约,swapExactTokensForTokens。
swapExactTokensForTokens 接受 5 个参数。
我们想要出售的代币数量 - amountIn
我们预期得到的代币数量 - amountOutMin
两个代币地址的数组 - [ buyToken, sellToken ]
买家钱包的地址 - addresses .me
交易的到期时间 - Date.now() + 1000 60 5 // 5分钟
注意:这只有在你拥有 WBNB 以购买代币和 BNB 以支付Gas费时才能工作!
调用该方法后,只需在成功购买后打印收据即可!
这就是我们机器人的全部内容!如果你在途中迷路了,这里有脚本的完整副本:
const ethers = require('ethers');
const addresses = {
WBNB: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",
router: "0x10ED43C718714eb63d5aA57B78B54704E256024E",
factory: "0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73",
me: "YOUR_WALLET_GOES_HERE"
}
const mnemonic = "your mnemonic goes here just like this .. .. .. .."
const provider = new ethers.providers.WebSocketProvider("__WEB_SOCKET_PROVIDER_FROM_QUICKNODE__")
const wallet = ethers.Wallet.fromMnemonic(mnemonic);
const account = wallet.connect(provider)
const factory = new ethers.Contract(
addresses.factory,
['event PairCreated(address indexed token0, address indexed token1, address pair, uint)'],
account
);
const router = new ethers.Contract(
addresses.router,
[\
'function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts)',\
'function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)',\
],
account
);
factory.on("PairCreated", async (token0, token1, addressPair) => {
console.log(`
~~~~~~~~~~~~~~~~~~
新的交易对被检测到
~~~~~~~~~~~~~~~~~~
token0: ${token0}
token1: ${token1}
addressPair: ${addressPair}
`);
// 此块确保我们使用 WBNB 进行支付
let buyToken, sellToken;
if(token0 === addresses.WBNB) {
buyToken = token0;
sellToken = token1;
}
if (token1 === addresses.WBNB) {
buyToken = token1;
sellToken = token0;
}
// 两个代币都不是 WBNB,我们无法购买
if(typeof buyToken === "undefined") {
return
}
const amountIn = ethers.utils.parseUnits('0.1', 'ether'); //ether 是测量单位,不是币
const amounts = await router.getAmountsOut(amountIn, [buyToken, sellToken]);
const amountOutMin = amounts[1].sub(amounts[1].div(10)); // JS 中大数的数学运算
console.log(`
~~~~~~~~~~~~~~~~~~~~
正在购买新代币
~~~~~~~~~~~~~~~~~~~~
buyToken: ${amountIn.toString()} ${buyToken} (WBNB)
sellToken: ${amountOutMin.toString()} ${sellToken}
`);
const tx = await router.swapExactTokensForTokens(
amountIn,
amountOutMin,
[buyToken, sellToken],
addresses.me,
Date.now() + 1000 * 60 * 5 //5分钟
);
const receipt = await tx.wait();
console.log('交易收据');
console.log(receipt);
}
)
如果你正确完成所有步骤,可以运行:
node bot.js
并看到机器人开始购买在 PancakeSwap 上开放的任何新代币!你可能见到诸如 "流动性不足" 或 "无法估算Gas价格" 等错误。请放心,这些都是因为新代币创建时出现的问题,而不是你这边的问题。如果你让脚本正常运行,你最终会在日志中收到一份购买的收据!
祝贺你在 DEX 上实施了完全自动的购买!你正在成为一个真正的 DeFi 市场制造者。我再次重申,这只是纯粹的概念验证,虽然你_理论上_可以从这样的策略中获利,但你可能不会。我不能推荐你在运行此类脚本时向你的钱包投入大量资金。本指南旨在让你了解这些机器人的工作方式,而不是让你赚钱。它也为你提供了一个出色的起点,供你自己跳跃!你可以修改或改进的方式是无穷无尽的。
你可以:
改为在听到信号后发送电子邮件或短信,而不是直接购买代币。这将允许你在购买之前进行尽职调查,而不是盲目购买。
让卖出过程自动化;这样你就不会长时间暴露于风险中。
添加更多参数以决定何时购买某种东西。除了仅监听代币的产生外,你还可以确保在购买之前达到你选择的任意阈值。
可能性是无穷的,仅受限于你的想象力和决心。
订阅我们的 新闻通讯,获取更多关于以太坊的文章和指南。如果你有任何反馈,请通过 Twitter 联系我们。你也可以在我们的 Discord 社区服务器上与我们聊天,这里聚集了一些你见过的最棒的开发者 😃
- 原文链接: quicknode.com/guides/def...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!