如何使用 web3 js 在 uniswap 上交换令牌
Posted
技术标签:
【中文标题】如何使用 web3 js 在 uniswap 上交换令牌【英文标题】:how to swap tokens on uniswap using web3 js 【发布时间】:2021-02-08 02:35:25 【问题描述】:我正在尝试使用 uniswap 合约方法来简单地将 eth 换成代币,使用 metamask 钱包中的 eth。 Uniswap 合约方式为:
function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
external
payable
returns (uint[] memory amounts);
我的天真印象是它应该看起来像这样,但我确信我错过了几个关键部分(如签署交易,使用适当的回调方法)并且我找不到完整的全面示例。一个完整的工作示例应该是什么样子?
const ETHaddress = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
const DAIaddress = "0x6b175474e89094c44da98b954eedeac495271d0f"
const routerContract = new web3.eth.Contract(
UniswapRouterABI,
"0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D"
);
routerContract.methods.swapExactETHForTokens(500,[ETHaddress,DAIaddress],myWalletAddress,someDeadline)
.send(from: myWalletAddress, value: "1000000000000")
【问题讨论】:
Uniswap 有一个 javascript SDK。如果你是新手开发者,我建议你使用他们的 SDK 而不是自己去弄明白。 @MikkoOhtamaa Uniswap SDK 不执行交易 AFAIK。 @lxx 你可能是对的。谢谢你纠正我。 【参考方案1】:您可以在 pancakeswap.finance 上查看此工作示例以进行购买: https://github.com/religion-counter/onlyone/blob/main/helper-scripts/buy-onlyone-pancakeswap.js
// Helper script that buys ONLYONE token from a specified address specified on text file SPECIFY_ACCOUNTS_YOU_WANT_TO_BUY_FOR_HERE.json
// The amount is specified with 'originalAmountToBuyWith' variable in the source
// The JSON file should have an array with objects with 'address' field and 'privateKey' field.
// Buys ONLYONE for $bnbAmount BNB from pancakeswap for address $targetAccounts[targetIndex].address
// targetIndex is passed as an argument: process.argv.splice(2)[0]
var fs = require('fs')
var Tx = require('ethereumjs-tx').Transaction;
var Web3 = require('web3')
var Common = require('ethereumjs-common').default;
var web3 = new Web3(new Web3.providers.HttpProvider('https://bsc-dataseed.binance.org/'))
var BSC_FORK = Common.forCustomChain(
'mainnet',
name: 'Binance Smart Chain Mainnet',
networkId: 56,
chainId: 56,
url: 'https://bsc-dataseed.binance.org/'
,
'istanbul',
);
// SPECIFY_THE_AMOUNT_OF_BNB_YOU_WANT_TO_BUY_FOR_HERE
var originalAmountToBuyWith = '0.007' + Math.random().toString().slice(2,7);
var bnbAmount = web3.utils.toWei(originalAmountToBuyWith, 'ether');
var targetAccounts = JSON.parse(fs.readFileSync('SPECIFY_ACCOUNTS_YOU_WANT_TO_BUY_FOR_HERE.json', 'utf-8'));
var targetIndex = Number(process.argv.splice(2)[0]);
var targetAccount = targetAccounts[targetIndex];
console.log(`Buying ONLYONE for $originalAmountToBuyWith BNB from pancakeswap for address $targetAccount.address`);
var res = buyOnlyone(targetAccounts[targetIndex], bnbAmount);
console.log(res);
async function buyOnlyone(targetAccount, amount)
var amountToBuyWith = web3.utils.toHex(amount);
var privateKey = Buffer.from(targetAccount.privateKey.slice(2), 'hex') ;
var abiArray = JSON.parse(JSON.parse(fs.readFileSync('onlyone-abi.json','utf-8')));
var tokenAddress = '0xb899db682e6d6164d885ff67c1e676141deaaa40'; // ONLYONE contract address
var WBNBAddress = '0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c'; // WBNB token address
// var onlyOneWbnbCakePairAddress = '0xd22fa770dad9520924217b51bf7433c4a26067c2';
// var pairAbi = JSON.parse(fs.readFileSync('cake-pair-onlyone-bnb-abi.json', 'utf-8'));
// var pairContract = new web3.eth.Contract(pairAbi, onlyOneWbnbCakePairAddress/*, from: targetAccount.address*/);
var amountOutMin = '100' + Math.random().toString().slice(2,6);
var pancakeSwapRouterAddress = '0x10ed43c718714eb63d5aa57b78b54704e256024e';
var routerAbi = JSON.parse(fs.readFileSync('pancake-router-abi.json', 'utf-8'));
var contract = new web3.eth.Contract(routerAbi, pancakeSwapRouterAddress, from: targetAccount.address);
var data = contract.methods.swapExactETHForTokens(
web3.utils.toHex(amountOutMin),
[WBNBAddress,
tokenAddress],
targetAccount.address,
web3.utils.toHex(Math.round(Date.now()/1000)+60*20),
);
var count = await web3.eth.getTransactionCount(targetAccount.address);
var rawTransaction =
"from":targetAccount.address,
"gasPrice":web3.utils.toHex(5000000000),
"gasLimit":web3.utils.toHex(290000),
"to":pancakeSwapRouterAddress,
"value":web3.utils.toHex(amountToBuyWith),
"data":data.encodeABI(),
"nonce":web3.utils.toHex(count)
;
var transaction = new Tx(rawTransaction, 'common': BSC_FORK );
transaction.sign(privateKey);
var result = await web3.eth.sendSignedTransaction('0x' + transaction.serialize().toString('hex'));
console.log(result)
return result;
如果有兴趣,您也可以为存储库做出贡献。
【讨论】:
var abiArray = JSON.parse(JSON.parse(fs.readFileSync('onlyone-abi.json','utf-8'))); 的 abi 代码是什么? 我一直有这个错误:错误:交易已被 EVM 还原:这是我使用 bscnan bscscan.com/tx/… 中可用的一些令牌进行的交易 有没有办法自动检索token的路径? @Mat.C 你可以查看 Uniswap github 中的github.com/religion-counter/onlyone/issues/10 和github.com/Uniswap/v2-sdk/blob/… 有一个函数可以计算给定输入和输出令牌的最佳路径。 我认为您还可以使用图形 API 查看给定令牌的所有对:docs.uniswap.org/protocol/V2/reference/API/… Pancakeswap 应该有类似的 API。问候【参考方案2】:首先你应该像下面这样登录你的 eth 帐户
const keystore = fs.readFileSync("your keystore path", "utf8");
var activeAccount = web3.eth.accounts.decrypt(keystore, password);
现在您可以签署和广播您的交易。您必须对您的交换消息进行编码并添加您的 tx 的数据字段。不要错过eth数量有多少想用token交换。
var swap = UniswapV2Router02Contract.methods.swapExactETHForTokens(amountOutMin, [WETH[activeChain].address, token.address], activeAccount.address, timeStamp)
var encodedABI = swap.encodeABI()
var tx =
from: activeAccount.address,
to: UniswapV2RouterAddress,
gas: 200000,
data: encodedABI,
value: ethAmount
;
var signedTx = await activeAccount.signTransaction(tx)
web3.eth.sendSignedTransaction(signedTx.rawTransaction)
.on('transactionHash', function(hash)
)
.on('confirmation', function(confirmationNumber, receipt)
)
.on('receipt', function(receipt)
)
.on('error', function(error, receipt) // If the transaction was rejected by the network with a receipt, the second parameter will be the receipt.
console.error("Error:", error, "Receipt:", receipt)
);
【讨论】:
在哪里可以找到 UniswapV2Router02Contract 可以发一个完整的例子吗? 你知道如何找到 UniswapV2Router02Contract @arisalexis 吗? 这里:etherscan.io/address/0x7a250d5630b4cf539739df2c5dacb4c659f2488d以上是关于如何使用 web3 js 在 uniswap 上交换令牌的主要内容,如果未能解决你的问题,请参考以下文章
解析 DeFi 项目之Uniswap(二): 如何使用Uniswap?
使用 web3.py 和 infura.io 监听 Uniswap 合约事件
在 swapExactTokensForTokens (UniswapV2Router02, web3.js) 期间恢复交易