泰山眾籌阿凡達(avatar)開發詳細丨泰山眾籌阿凡達(avatar)系統開發(開發及原始碼)

xiaofufu發表於2023-03-01

  Specifically,new retail is consumer-centered,based on the digitalization of people,goods and services,supply chain and other links,connecting various consumption scenarios through data flow,including smart phones,mobile terminals,computers,physical stores,and new ways that can be realized in the future,and using digital technology to realize the comprehensive integration of physical and virtual retail supply chain,transaction delivery chain,and service chain,It provides consumers with a seamless consumption experience covering all channels,and is an efficient and inclusive pan-retail business characterized by logistics distribution replacing physical delivery.


  //****SWAP****


  //requires the initial amount to have already been sent to the first pair


  //交易方法


  //需要先將amounts[0]的金額已經轉到第一個pair地址(即path[0]+path[1]組成的pair)!


  function _swap(uint[]memory amounts,address[]memory path,address _to)internal virtual{


  for(uint i;i<path.length-1;i++){//遍歷整個path


  //得到進/出token地址


  (address input,address output)=(path<i>,path[i+1]);


  //排序得到token0


  (address token0,)=UniswapV2Library.sortTokens(input,output);


  //獲取到output幣種的輸出量!


  uint amountOut=amounts[i+1];


  //根據token0,input得到amount0需要out,還是amount1是out,;注意其中之一一定是0,即入token的金額,不需要pair轉出


  (uint amount0Out,uint amount1Out)=input==token0?(uint(0),amountOut):(amountOut,uint(0));


  //如果i小於path長度-2,就表示還需要繼續交易,所以to是下一個交易對,如果一樣就表示path結束了,to就是引數中的_to


  address to=i<path.length-2?UniswapV2Library.pairFor(factory,output,path[i+2]):_to;


  //呼叫pair的swap方法,其中一個out是0,另一個是要轉出的金額,內部是轉出輸出量,並校驗交易是否正確,更新儲備量


  IUniswapV2Pair(UniswapV2Library.pairFor(factory,input,output)).swap(


  amount0Out,amount1Out,to,new bytes(0)


  );需求及模式介紹:MrsFu123


  }


  }


  //輸入精確的token,換取另一個token(輸出量不確定)


  function swapExactTokensForTokens(


  uint amountIn,//輸入金額


  uint amountOutMin,//最小輸出金額


  address[]calldata path,//交易路徑


  address to,


  uint deadline


  )external virtual override ensure(deadline)returns(uint[]memory amounts){


  //透過getAmountsOut獲取整個path完整路徑的輸入/出量,下標0是使用者實際輸入額,最後一個位置是實際輸出額


  amounts=UniswapV2Library.getAmountsOut(factory,amountIn,path);


  //需要滿足計算得來最終輸出量大於等於最小輸出金額


  require(amounts[amounts.length-1]>=amountOutMin,'UniswapV2Router:INSUFFICIENT_OUTPUT_AMOUNT');


  //先將amounts[0]入金額轉入第一個pair!!


  TransferHelper.safeTransferFrom(


  path[0],msg.sender,UniswapV2Library.pairFor(factory,path[0],path[1]),amounts[0]


  );


  //呼叫內部_swap方法


  _swap(amounts,path,to);


  }


  //輸入不確定數量A,換取精確輸出的B(例:精確輸出1個token,正常100u可以換1個token,由於發交易後其他人先交易過,導致價格變了,可能95或者105可以買1個token,95肯定交易透過,如果amountInMax是102,該交易就無法成交,回退)


  function swapTokensForExactTokens(


  uint amountOut,//精確的輸出額


  uint amountInMax,//最大允許的輸入量


  address[]calldata path,


  address to,


  uint deadline


  )external virtual override ensure(deadline)returns(uint[]memory amounts){


  //根據getAmountsIn計算出輸入輸出量


  amounts=UniswapV2Library.getAmountsIn(factory,amountOut,path);


  //需要第一個輸入量小於等於計算來的實際輸入量


  require(amounts[0]<=amountInMax,'UniswapV2Router:EXCESSIVE_INPUT_AMOUNT');


  //將計算得來的金額amounts[0]轉入第一個pair


  TransferHelper.safeTransferFrom(


  path[0],msg.sender,UniswapV2Library.pairFor(factory,path[0],path[1]),amounts[0]


  );


  //呼叫內部_swap方法


  _swap(amounts,path,to);


  }


  //輸入精確的eth換取不定量的token,對應swapExactTokensForTokens,不過輸入的是eth,換成weth就一樣了


  function swapExactETHForTokens(uint amountOutMin,address[]calldata path,address to,uint deadline)


  external


  virtual


  override


  payable


  ensure(deadline)


  returns(uint[]memory amounts)


  {


  //要求path[0]是weth地址


  require(path[0]==WETH,'UniswapV2Router:INVALID_PATH');


  //透過getAmountsOut,輸入額是msg.value


  amounts=UniswapV2Library.getAmountsOut(factory,msg.value,path);


  //需要滿足計算得來最終輸出量大於等於最小輸出金額


  require(amounts[amounts.length-1]>=amountOutMin,'UniswapV2Router:INSUFFICIENT_OUTPUT_AMOUNT');


  //pair中只會存weth,沒有eth


  IWETH(WETH).deposit{value:amounts[0]}();//兌換成weth


  //將weth轉入到第一個pair


  assert(IWETH(WETH).transfer(UniswapV2Library.pairFor(factory,path[0],path[1]),amounts[0]));


  //呼叫內部_swap方法


  _swap(amounts,path,to);


  }


  //輸入不定量的A,換取精確的輸出ETH,對應swapTokensForExactTokens,只是內部將weth轉成eth再給使用者


  function swapTokensForExactETH(uint amountOut,uint amountInMax,address[]calldata path,address to,uint deadline)


  external


  virtual


  override


  ensure(deadline)


  returns(uint[]memory amounts)


  {


  //path最後一個輸出地址是weth


  require(path[path.length-1]==WETH,'UniswapV2Router:INVALID_PATH');


  //


  amounts=UniswapV2Library.getAmountsIn(factory,amountOut,path);


  //需要第一個輸入量小於等於計算來的實際輸入量


  require(amounts[0]<=amountInMax,'UniswapV2Router:EXCESSIVE_INPUT_AMOUNT');


  //將計算得來的金額amounts[0]轉入第一個pair


  TransferHelper.safeTransferFrom(


  path[0],msg.sender,UniswapV2Library.pairFor(factory,path[0],path[1]),amounts[0]


  );


  //呼叫內部_swap方法,注意第三個引數改成了當前路由地址!


  _swap(amounts,path,address(this));


  //交換成功後,將weth轉換成eth,再轉給to


  IWETH(WETH).withdraw(amounts[amounts.length-1]);


  TransferHelper.safeTransferETH(to,amounts[amounts.length-1]);


  }


  //輸入精確的A換取不定量的eth swapExactTokensForTokens只是輸出是eth


  function swapExactTokensForETH(uint amountIn,uint amountOutMin,address[]calldata path,address to,uint deadline)


  external


  virtual


  override


  ensure(deadline)


  returns(uint[]memory amounts)


  {


  //path最後一個輸出地址是weth


  require(path[path.length-1]==WETH,'UniswapV2Router:INVALID_PATH');


  //


  amounts=UniswapV2Library.getAmountsOut(factory,amountIn,path);


  //注意輸出要大於最小輸出


  require(amounts[amounts.length-1]>=amountOutMin,'UniswapV2Router:INSUFFICIENT_OUTPUT_AMOUNT');


  //


  TransferHelper.safeTransferFrom(


  path[0],msg.sender,UniswapV2Library.pairFor(factory,path[0],path[1]),amounts[0]


  );


  //呼叫內部_swap方法,注意第三個引數改成了當前路由地址!


  _swap(amounts,path,address(this));


  //交換成功後,將weth轉換成eth,再轉給to


  IWETH(WETH).withdraw(amounts[amounts.length-1]);


  TransferHelper.safeTransferETH(to,amounts[amounts.length-1]);


  }


  //輸入不定量的ETH換取精確的token輸出,對應swapTokensForExactTokens,只是輸入的是eth


  function swapETHForExactTokens(uint amountOut,address[]calldata path,address to,uint deadline)


  external


  virtual


  override


  payable


  ensure(deadline)


  returns(uint[]memory amounts)


  {


  require(path[0]==WETH,'UniswapV2Router:INVALID_PATH');


  amounts=UniswapV2Library.getAmountsIn(factory,amountOut,path);


  //注意,實際輸入需要小於msg.value,即eth輸入量


  require(amounts[0]<=msg.value,'UniswapV2Router:EXCESSIVE_INPUT_AMOUNT');


  IWETH(WETH).deposit{value:amounts[0]}();


  assert(IWETH(WETH).transfer(UniswapV2Library.pairFor(factory,path[0],path[1]),amounts[0]));


  _swap(amounts,path,to);


  //refund dust eth,if any


  //如果實際不需要那麼多eth,將剩餘返還使用者


  if(msg.value>amounts[0])TransferHelper.safeTransferETH(msg.sender,msg.value-amounts[0]);


  }


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69956839/viewspace-2937548/,如需轉載,請註明出處,否則將追究法律責任。

相關文章