泰山眾籌阿凡達(avatar)開發詳細丨泰山眾籌阿凡達(avatar)系統開發(開發及原始碼)
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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 泰山眾籌阿凡達avatar開發功能丨泰山眾籌阿凡達avatar系統開發流程及原始碼分析原始碼
- Avatar阿凡達泰山眾籌商城開發上線版丨Avatar阿凡達泰山眾籌商城系統開發(開發原始碼)原始碼
- Avatar阿凡達泰山眾籌開發案例版丨Avatar阿凡達泰山眾籌系統開發(開發邏輯及方案)
- 阿凡達泰山眾籌開發系統丨阿凡達泰山眾籌系統開發(詳情版)丨阿凡達泰山眾籌原始碼開發原始碼
- 阿凡達泰山眾籌開發原理丨阿凡達泰山眾籌系統開發(方案及詳細)
- 泰山眾籌(阿凡達)系統開發成熟及方案丨泰山眾籌阿凡達開發原始碼功能原始碼
- Avatar阿凡達泰山眾籌系統開發(模式)|Avatar阿凡達需求方案部署模式
- Avatar阿凡達泰山眾籌開發|眾籌系統DAPP開發技術APP
- 阿凡達(泰山眾籌)開發案例版丨阿凡達(泰山眾籌)系統開發(規則及原始碼)原始碼
- 深入分析:Avatar阿凡達泰山眾籌系統開發
- 阿凡達(Avatar)泰山眾籌商城系統開發技術詳細及案例
- 阿凡達泰山眾籌開發(功能)丨阿凡達泰山眾籌系統開發(成熟方案及案例)
- 泰山眾籌4.0阿凡達開發原理丨泰山眾籌4.0阿凡達系統開發詳細技術及原始碼分析原始碼
- 泰山眾籌(阿凡達4.0)系統開發流程及分析丨泰山眾籌(阿凡達4.0)開發原始碼功能原始碼
- 泰山眾籌(阿凡達)開發邏輯丨泰山眾籌(阿凡達)系統開發成熟案例及原始碼分析原始碼
- Avatar阿凡達(泰山眾籌)系統開發技術詳情及方案原始碼原始碼
- 深入分析阿凡達Avatar泰山眾籌系統開發詳細方案及案例原始碼原始碼
- 阿凡達泰山眾籌商城開發(系統)丨阿凡達泰山眾籌系統開發(開發穩定版)
- 什麼是阿凡達泰山眾籌系統開發丨阿凡達泰山眾籌系統開發(dapp開發技術)APP
- 阿凡達泰山眾籌開發正式版丨阿凡達泰山眾籌系統開發流程及原始碼(web3.0技術開發)原始碼Web
- 泰山眾籌系統丨及泰山眾籌系統開發原始碼部署(技術開發流程)泰山眾籌原始碼
- 阿凡達泰山眾籌系統開發Avata模式模式
- sun4.0泰山眾籌系統開發(模式案例)|阿凡達泰山眾籌sun開發方案模式
- 泰山眾籌商城開發、泰山眾籌DAPP系統開發、泰山眾籌原始碼部署開發APP原始碼
- 泰山眾籌阿凡達系統開發模式邏輯模式
- Avatar泰山眾籌系統開發搭建詳情邏輯
- AVATAR阿凡達合約系統?區塊鏈阿凡達泰山眾籌專案邏輯系統開發功能及原始碼區塊鏈原始碼
- 關於泰山眾籌4.0/阿凡達眾籌系統/技術開發
- 泰山眾籌系統Dapp開發/泰山眾籌原始碼/泰山眾籌矩陣開發方案APP原始碼矩陣
- 阿凡達Avata泰山眾籌系統開發技術搭建
- 阿凡達Sun4眾籌開發系統搭建|泰山眾籌模式系統原始碼部署模式原始碼
- 泰山眾籌商城系統開發(實現方案)丨泰山眾籌商城開發原始碼及功能原始碼
- AVATAR阿凡達眾籌系統開發說明合約技術
- 深入瞭解阿凡達泰山眾籌商城系統開發詳情版及原始碼功能原始碼
- sun4.0阿凡達Avatar系統開發技術詳細丨阿凡達Avatar系統原始碼原始碼
- 泰山眾籌APP開發,泰山眾籌商城開發,泰山眾籌是什麼模式?APP模式
- 泰山眾籌4.0商城開發詳情丨泰山眾籌4.0商城系統開發實現技術案例及原始碼原始碼
- 關於泰山眾籌模式系統開發邏輯分析丨泰山眾籌DAPP模式詳細開發方案(原始碼部署)模式APP原始碼