pancakeswap 的代幣價格
實際上,我想知道如何從 pancakeswap 中檢索低帽代幣的價格,而不必直接使用 poocoin/dextools 之類的網站。
我明白了這一點,
- 你可以在這裡使用 pancakeswap api ,但它不適用於每個令牌
- 您可以直接使用 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.84
是reserve1=7691.065744229067
浮點數,如果在calcPriceInBnb
此數字中使用,則返回令牌的正確價格。假設我在同一時刻查詢了 bsc 池合約,而不是我會得到的值
reserve0=16537136228273284
(reserve1=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>)