NodeJS Uniswap USDC=>ETH交换

mrphzbgm  于 2023-02-08  发布在  Node.js
关注(0)|答案(1)|浏览(127)

尝试通过Uniswap和以太网将USDC交换到ETH,但一直出错。

  1. async function swapUsdcToEth(amount, walledAddress) {
  2. const usdc = await Fetcher.fetchTokenData(chainId, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48');
  3. const eth = await Fetcher.fetchTokenData(chainId, '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2');
  4. const pair = await Fetcher.fetchPairData(usdc, eth);
  5. const route = new Route([pair], usdc);
  6. const amountIn = new TokenAmount(usdc, amount);
  7. const trade = new Trade(route, amountIn, TradeType.EXACT_INPUT);
  8. const slippageTolerance = new Percent('50', '10000');
  9. const value = ethers.BigNumber.from(trade.inputAmount.raw.toString()).toHexString();
  10. const amountOutMin = ethers.BigNumber.from(trade.minimumAmountOut(slippageTolerance).raw.toString()).toHexString();
  11. const deadline = Math.floor(Date.now() / 1000) + 60 * 20;
  12. const uniswapRouterV2Address = '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D';
  13. const provider = new ethers.providers.JsonRpcProvider('https://mainnet.infura.io/v3/b9fkdmkdkdv4937b52ea9637cf1d1bd');
  14. const signer = new ethers.Wallet(walledAddress, provider);
  15. const uniswap = new ethers.Contract(
  16. uniswapRouterV2Address,
  17. ['function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts)'],
  18. signer
  19. );
  20. try {
  21. const tx = await uniswap.swapExactTokensForETH(value, amountOutMin, [walledAddress], walledAddress, deadline);
  22. const receipt = await tx.wait();
  23. console.log('transaction was mined in block', receipt.blockNumber);
  24. } catch (e) {
  25. console.log(e);
  26. }
  27. }

接收错误如下:'错误:无法估计气体;交易可能失败或可能需要手动气体限制“。我做错了什么?

nwsw7zdq

nwsw7zdq1#

所以看起来可能有几件事。你批准你的令牌被路由器使用了吗?而且我没有看到任何气体设置在那里
这是一个工作版本,我已经修改,使工作(这是设置测试在一个主网分支,但它使用的实时数据(作为阿尔法路由器是只为主网活,所以实时数据和分支数据将随着时间的推移而变化,并导致交易错误,所以重置分支使用前)
使主网只取出本地提供商,将所有提供商改为主网提供商。
谨慎使用,我不完美,不作任何保证:检查滑动和所有变量
这是作为TOKEN到TOKEN Exact_Input交换构建的,WETH存款为1 ETH。要使用ETH,您可以在批准中删除Weth存款和令牌,并使用BigNumber.from(typedValueParsed)作为事务的值,而不是0
由于我不知道EtherJS的天然气价格和天然气限额的存款和批准是一个单位100 gwei和300k的限制,并应修改为目前的网络天然气价格和估计的天然气限额。

  1. import { AlphaRouter } from '@uniswap/smart-order-router'
  2. import { Token, CurrencyAmount } from '@uniswap/sdk-core'
  3. import { JSBI, Percent } from "@uniswap/sdk";
  4. import { ethers, BigNumber } from "ethers";
  5. const V3_SWAP_ROUTER_ADDRESS = "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45";
  6. const TokenInput = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";
  7. const TokenOutput = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
  8. const web3Provider = new ethers.providers.JsonRpcProvider("https://eth-mainnet.alchemyapi.io/v2/");
  9. const web3 = new ethers.providers.JsonRpcProvider("http://127.0.0.1:8545/");
  10. const privateKey = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80";
  11. const wallet = new ethers.Wallet(privateKey,web3);
  12. const address = wallet.address;
  13. import * as fs from 'fs';
  14. let UniV3RouterAbi = fs.readFileSync('NewUniRouter.json');
  15. const V3routerAbi = JSON.parse(UniV3RouterAbi);
  16. let ERC20Abi = fs.readFileSync('ERC20.json');
  17. const ERC20 = JSON.parse(ERC20Abi);
  18. let WETHAbij = fs.readFileSync('WETHAbi.json');
  19. const WETHAbi = JSON.parse(WETHAbij);
  20. async function log(inpt){
  21. console.log(inpt);
  22. console.log("");
  23. }
  24. async function TokBal(tokens){
  25. var ERC20contract = new ethers.Contract(tokens, ERC20, web3);
  26. var myERC20bal = await ERC20contract.balanceOf(wallet.address);
  27. return myERC20bal;
  28. }
  29. async function Deposit(amt){
  30. var WethC = new ethers.Contract(TokenInput, WETHAbi, web3);
  31. var datac = await WethC.populateTransaction["deposit"]();
  32. var ncn = await wallet.getTransactionCount();
  33. const transaction = {
  34. data: datac.data,
  35. nonce: ncn,
  36. to: TokenInput,
  37. value: BigNumber.from(amt),
  38. from: wallet.address,
  39. gasPrice: '0x174876e800',
  40. gasLimit: '0x493e0',
  41. };
  42. const signedTx = await wallet.signTransaction(transaction);
  43. const txHash = await web3.sendTransaction(signedTx);
  44. log(txHash.hash);
  45. }
  46. async function Approve(Toked, amt){
  47. var WethC = new ethers.Contract(Toked, ERC20, web3);
  48. var datac = await WethC.populateTransaction["approve"](V3_SWAP_ROUTER_ADDRESS, amt);
  49. var ncn = await wallet.getTransactionCount();
  50. const transaction = {
  51. data: datac.data,
  52. nonce: ncn,
  53. to: Toked,
  54. value: BigNumber.from("0"),
  55. from: wallet.address,
  56. gasPrice: '0x174876e800',
  57. gasLimit: '0x493e0',
  58. };
  59. const signedTx = await wallet.signTransaction(transaction);
  60. const txHash = await web3.sendTransaction(signedTx);
  61. log(txHash.hash);
  62. var appFor = await WethC.callStatic.allowance(wallet.address, V3_SWAP_ROUTER_ADDRESS);
  63. log("Approved : "+appFor.toString());
  64. }
  65. const router = new AlphaRouter({ chainId: 1, provider: web3Provider });
  66. const WETH = new Token(
  67. router.chainId,
  68. '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
  69. 18,
  70. 'WETH',
  71. 'Wrapped Ether'
  72. );
  73. const USDC = new Token(
  74. router.chainId,
  75. '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
  76. 6,
  77. 'USDC',
  78. 'USD//C'
  79. );
  80. const typedValueParsed = '1000000000000000000';
  81. const wethAmount = CurrencyAmount.fromRawAmount(WETH, JSBI.BigInt(typedValueParsed));
  82. const IO = "Exact_Input"
  83. const TradeType = IO == "Exact_Input" ? 0 : 1;
  84. const route = await router.route(
  85. wethAmount,
  86. USDC,
  87. TradeType,
  88. {
  89. recipient: wallet.address,
  90. slippageTolerance: new Percent(5, 100),
  91. deadline: Math.floor(Date.now()/1000 +1800)
  92. }
  93. );
  94. var Ebal = await web3.getBalance(wallet.address);
  95. log("Wallet Balance : "+Ebal.toString());
  96. var tbal = await TokBal(TokenOutput);
  97. log("Token Out Balance : "+tbal.toString());
  98. await Deposit("1000000000000000000");
  99. await Approve(TokenInput,"1000000000000000000");
  100. var tbalW = await TokBal(TokenInput);
  101. log("Token In Balance : "+tbalW.toString());
  102. log(`Quote Exact In: ${route.quote.toFixed(wethAmount.currency === WETH ? USDC.decimals : WETH.decimals)}`);
  103. log(`Gas Adjusted Quote In: ${route.quoteGasAdjusted.toFixed(wethAmount.currency === WETH ? USDC.decimals : WETH.decimals)}`);
  104. var nc = await wallet.getTransactionCount();
  105. const transaction = {
  106. data: route.methodParameters.calldata,
  107. nonce: nc,
  108. to: V3_SWAP_ROUTER_ADDRESS,
  109. value: BigNumber.from(0),
  110. from: wallet.address,
  111. gasPrice: BigNumber.from(route.gasPriceWei),
  112. gasLimit: BigNumber.from(route.estimatedGasUsed).add(BigNumber.from("50000")),
  113. };
  114. const signedTx = await wallet.signTransaction(transaction);
  115. const PretxHash = ethers.utils.keccak256(signedTx);
  116. const txHash = await web3.sendTransaction(signedTx)
  117. log(txHash.hash);
  118. var Ebal = await web3.getBalance(wallet.address);
  119. log("Wallet Balance : "+Ebal.toString());
  120. var tbal = await TokBal(TokenOutput);
  121. log("Token Out Balance : "+tbal.toString());
  122. var tbalW = await TokBal(TokenInput);
  123. log("Token In Balance : "+tbalW.toString());

要获取ETH,请使用此标记代替输出标记

  1. outPutAddress === WETH9[chainId].address ? nativeOnChain(chainId) : outPutToken,

编辑〉〉〉〉〉〉〉〉〉〉修改为新版本

  1. import { ethers } from 'ethers'
  2. import {AlphaRouter, ChainId, SwapType, nativeOnChain} from '@uniswap/smart-order-router'
  3. import { TradeType, CurrencyAmount, Percent, Token } from '@uniswap/sdk-core'
  4. import { TickMath } from '@uniswap/v3-sdk';
  5. import JSBI from 'jsbi';
  6. import bn from 'bignumber.js'
  7. async function main() {
  8. const MY_ADDRESS = "<ADDRESS>";
  9. const web3Provider = new ethers.providers.JsonRpcProvider('https://eth-mainnet.alchemyapi.io/v2/<RPC_KEY>')
  10. const router = new AlphaRouter({ chainId: 1, provider: web3Provider });
  11. const WETH = new Token(
  12. 1,
  13. '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
  14. 18,
  15. 'WETH',
  16. 'Wrapped Ether'
  17. );
  18. const USDC = new Token(
  19. ChainId.MAINNET,
  20. '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
  21. 6,
  22. 'USDC',
  23. 'USD//C'
  24. );
  25. const AAVE = new Token(
  26. ChainId.MAINNET,
  27. '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9',
  28. 18,
  29. 'AAVE',
  30. 'AAVE'
  31. );
  32. const options = {
  33. recipient: MY_ADDRESS,
  34. slippageTolerance: new Percent(10, 1000),
  35. deadline: Math.floor(Date.now() / 1000 + 1800),
  36. type: SwapType.SWAP_ROUTER_02,
  37. }
  38. const typedValueParsed = '10000000000000000000'
  39. const route = await router.route(
  40. CurrencyAmount.fromRawAmount(
  41. AAVE,
  42. typedValueParsed.toString()
  43. ),
  44. nativeOnChain(ChainId.MAINNET),
  45. TradeType.EXACT_INPUT,
  46. options
  47. )
  48. console.log(`Quote Exact In: ${route.quote.toFixed(route.quote.currency.decimals)}`);
  49. console.log(`Gas Adjusted Quote In: ${route.quoteGasAdjusted.toFixed(route.quote.currency.decimals)}`);
  50. console.log(`Gas Used USD: ${route.estimatedGasUsedUSD.toFixed(2)}`);
  51. console.log(route.methodParameters.calldata);
  52. }
  53. main()
展开查看全部

相关问题