Tokens

pancakeswap 的代幣價格

  • March 22, 2022

實際上,我想知道如何從 pancakeswap 中檢索低帽代幣的價格,而不必直接使用 poocoin/dextools 之類的網站。

我明白了這一點,

  1. 你可以在這裡使用 pancakeswap api ,但它不適用於每個令牌
  2. 您可以直接使用 bsc 上的代幣池合約來檢索價格(在此範例中假設池為 BNB/您的代幣)

我選擇第二種方式,因為它適用於所有令牌,這就是我所做的:

  • 我紅了主 pancakeswap 合約(0x10ED43C718714eb63d5aA57B78B54704E256024E),發現這個函式用於計算輸出中的代幣價格
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) {
       require(amountIn > 0, 'PancakeLibrary: INSUFFICIENT_INPUT_AMOUNT');
       require(reserveIn > 0 && reserveOut > 0, 'PancakeLibrary: INSUFFICIENT_LIQUIDITY');
       uint amountInWithFee = amountIn.mul(9975);
       uint numerator = amountInWithFee.mul(reserveOut);
       uint denominator = reserveIn.mul(10000).add(amountInWithFee);
       amountOut = numerator / denominator;
   }
  • 我將上層函式轉換為 javascript 普通函式以直接使用它。
function calcPriceInBnb( amountIn, reserveIn, reserveOut ){
   let amountInWithFee = amountIn *  9975 ;
   let numerator = amountInWithFee * reserveOut ;
   let denominator = ( reserveIn * 10000 ) + amountInWithFee ;
   console.log( numerator, denominator)
   amountOut = numerator / denominator;
   return amountOut;
}
console.log( calcPriceInBnb (
       1,
       parseFloat(reserves_._reserve1),
       toBaseUnit(reserves_._reserve0, 18, web3.utils.BN)
   ) ) // usage example
  • 現在在令牌池(0x1d42d057b765177298735c8d9f36b8208449dbb3)上,我正在呼叫該函式來檢索池儲備
function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
  • 一旦我有了我呼叫的儲備金calcPriceInBnb(1, reserve1, reserve0),它會以 BNB 的形式返回代幣價格,然後我只需將 BNB 價值轉換為美元。

我發現只有一個問題,當我從池中獲得 reseves 時,我得到一個非浮點數。

例如:我看到dextools.io使用相同的方法來計算代幣的價格,檢查網站上的請求,它使用帶有以下鍵的 json bojects

{
  "data":{
     "pair":{
        "token0":{
           "_id":"6096efc237e2488af0c1ea10",
           "id":"0x4a824ee819955a7d769e03fe36f9e0c3bd3aa60b",
           "name":"Kabosu",
           "symbol":"KABOSU",
           "decimals":9
        },
        "token1":{
           "_id":"6096efc237e2488af0c1ea11",
           "id":"0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c",
           "name":"Wrapped BNB",
           "symbol":"WBNB",
           "decimals":18
        },
        "info":{
           "address":"0x4a824ee819955a7d769e03fe36f9e0c3bd3aa60b",
           "holders":121190
        },
        "_id":"6096efc237e2488af0c1ea0f",
        "id":"0xa17d2c8b629095672633828d744a03608bbaae24",
        "createdAtTimestamp":1620504512,
        "exchange":"pancakev2",
        "type":"standard-pair",
        "tokenIndex":0,
        "__v":0,
        "initialReserve0":365615229923141.8,
        "initialReserve1":208.675,
        "creation":{
           "blockNumber":"7250792",
           "timeStamp":"1620504512",
           "hash":"0x4d1e5b7082d0a92885cad5a7047b2693c7e2790be0c591a622d602ef7318b3be",
           "nonce":"0",
           "blockHash":"0x7bdf8d219600934504103326070861fd3c99fefcbc9535592e042dd369686996",
           "transactionIndex":"213",
           "from":"0xb56fd23449d66a10251e7efa778c944c4ba96666",
           "to":"",
           "value":"0",
           "gas":"5956167",
           "gasPrice":"5000000000",
           "isError":"0",
           "txreceipt_status":"1",
           "input":"",
           "contractAddress":"0x4a824ee819955a7d769e03fe36f9e0c3bd3aa60b",
           "cumulativeGasUsed":"32279124",
           "gasUsed":"5956167",
           "confirmations":"235853"
        },
        "reserve0":165371362282732.84,
        "reserve1":7691.065744229067,
        "reserveUpdatedAt":1622012556573,
        "txCount":244654
     }
  }
}

正如您在對象末尾看到的那樣,有兩個欄位reserve0=165371362282732.84reserve1=7691.065744229067浮點數,如果在calcPriceInBnb此數字中使用,則返回令牌的正確價格。

假設我在同一時刻查詢了 bsc 池合約,而不是我會得到的值reserve0=16537136228273284reserve1=7691065744229067非浮點數),這讓我得到了錯誤的計算。

我認為這與decimals池中的代幣有關,但沒有找到相關性。任何的想法?

更新

我在 github 上做了一個關於它的要點https://gist.github.com/Linch1/ede03999f483f2b1d5fcac9e8b312f2c

你不需要經歷這個麻煩,你可以在 PancakeSwap 路由器合約上使用 getAmount **s Out 來簡化這個過程。**您提供要使用的路徑中第一個令牌的路徑和數量,該函式返回您當時將收到的令牌數量。然後,您可以使用此數據進行價格計算。

這是一個範例,您可以如何在 Uniswap、Pancakeswap、SpookySwap、WannaSwap 等平台上獲取任何代幣的價格……其中大多數都是從原始 Uniswap 合約分叉並共享相同的界面。

import Web3 from "web3";
import { toWei, fromWei } from "web3-utils";

const abi = [
 {
   name: "getAmountsOut",
   type: "function",
   inputs: [
     {
       name: "amountIn",
       type: "uint256",
     },
     { name: "path", type: "address[]" },
   ],
   outputs: [{ name: "amounts", type: "uint256[]" }],
 },
];

const web3 = new Web3("<put_here_rpc_endpoint>");
const dexRouter = new web3.eth.Contract(
 abi,
 "<put_here_address_of_dex_router>"
);

const getTokenExchangeRate = async (tokenA, tokenB) => {
 return (
   await dexRouter.methods.getAmountsOut(toWei("1"), [tokenA, tokenB]).call()
 )[1];
};

// usage
const price = await getTokenExchangeRate(<addressForTokenA>, <addressForTokenB>)

引用自:https://ethereum.stackexchange.com/questions/99690