Uniswap交易所系統(tǒng)丨uniswap交易所系統(tǒng)開(kāi)發(fā)
在進(jìn)行兩個(gè)代幣交易時(shí),是首先需要在鏈下計(jì)算出交易的路徑,例如使用ETH->DAI: 可以直接通過(guò)ETH/DAI的交易池完成 也可以通過(guò)ETH->USDC->DAI路徑,即經(jīng)過(guò)ETH/USDC,USDC/DAI兩個(gè)交易池完成交易 Uniswap的前端會(huì)幫用戶實(shí)時(shí)計(jì)算出最優(yōu)路徑(即交易的收益最高),作為參數(shù)傳給合約調(diào)用。前端中這部分計(jì)算的具體實(shí)現(xiàn)在這里,具體過(guò)程為先用需要交易的輸入代幣,輸出代幣,以及一系列可用的中間代幣(代碼中叫Base token)生成所有的路徑(當(dāng)然為了降低復(fù)雜度,路徑中最多包含3個(gè)代幣),然后遍歷每個(gè)路徑輸出的輸出代幣數(shù)量,最后選取最佳路徑。 交易的入口函數(shù)是exactInput函數(shù),代碼如下: struct ExactInputParams{開(kāi)發(fā)案例I35功能7o98源碼o7I8 bytes path;//路徑 address recipient;//收款地址 uint256 deadline;//交易有效期 uint256 amountIn;//輸入的token數(shù)(輸入的token地址就是path中的第一個(gè)地址) uint256 amountOutMinimum;//預(yù)期交易最少獲得的token數(shù)(獲得的token地址就是path中最后一個(gè)地址) } function exactInput(ExactInputParams memory params) external payable override checkDeadline(params.deadline) returns(uint256 amountOut) {開(kāi)發(fā)成品:mrsfu123 //通過(guò)循環(huán),遍歷傳入的路徑,進(jìn)行交易 while(true){ bool hasPools=params.path.hasPools(); //完成當(dāng)前路徑的交易 params.amountIn=exactInputSingle( params.amountIn, //如果是中間交易,又合約代為收取和支付中間代幣 hasPools?address(this):params.recipient, //給回調(diào)函數(shù)用的參數(shù) SwapData({ path:params.path.getFirstPool(), payer:msg.sender }) ); //如果路徑全部遍歷完成,則退出循環(huán),交易完成 if(hasPools){ //步進(jìn)path中的值 params.path=params.path.skipToken(); }else{ amountOut=params.amountIn; break; } } //檢查交易是否滿足預(yù)期 require(amountOut>=params.amountOutMinimum,'Too little received'); }