什么是智能合约DApp。智能合约DApp是使用区块链技术实现去中心化应用(DApp)的核心技术。所谓智能合约是指以数字代码的形式编写的自动执行计算机程序,实现了相互协作的各方之间的权益自动执行和管理的智能合约系统。
区块链技术是Web3.0的基础技术,它可以提供去中心化的信任和安全保障。
智能合约语言:目前Solidity是主要语言之一,因为以太坊作为最广泛使用的区块链平台之一,它支持Solidity语言作为智能合约的编写语言。此外,还有其他语言可用于开发智能合约,如Vyper和Serpent等。
区块链是一个分布式数据库,其中存储了所有交易的信息,每个区块都包含了前一个区块的哈希值,从而构成了一个不可篡改的链。
去中心化存储是指将数据存储在多个节点上而不是集中在一个中心化的服务器上。
contract UniswapV2Router01 is IUniswapV2Router01{
address public immutable override factory;
address public immutable override WETH;
modifier ensure(uint deadline){
require(deadline>=block.timestamp,'UniswapV2Router:EXPIRED');
_;
}
constructor(address _factory,address _WETH)public{
factory=_factory;
WETH=_WETH;
}
receive()external payable{
assert(msg.sender==WETH);//only accept ETH via fallback from the WETH contract
}
//ADD LIQUIDITY
//返回值:填充A,B数量
//添加流动池
//这个函数是为了计算往池子里填充A,B数量
function _addLiquidity(
address tokenA,//A地址
address tokenB,//B地址
uint amountADesired,//A的填充量
uint amountBDesired,//B的填充量
uint amountAMin,//A的填充量最小值
uint amountBMin//B的填充量最小值
)private returns(uint amountA,uint amountB){
//如果不存在这个交易对,那么新建一个
if(IUniswapV2Factory(factory).getPair(tokenA,tokenB)==address(0)){
IUniswapV2Factory(factory).createPair(tokenA,tokenB);
}
//获取当前池子A,B的储备量
(uint reserveA,uint reserveB)=UniswapV2Library.getReserves(factory,tokenA,tokenB);
if(reserveA==0&&reserveB==0){
//新建的池子,直接填充
(amountA,amountB)=(amountADesired,amountBDesired);
}
else{
//如果两个储备量不为0,需要根据当前的价格/比例去新增流动性
//按A的比例填充B的数量
//AA/BB=A/B-->AA=BB*(A/B)
uint amountBOptimal=UniswapV2Library.quote(amountADesired,reserveA,reserveB);
//amountBMin<=amountBOptimal<=amountBDesired
if(amountBOptimal<=amountBDesired){
require(amountBOptimal>=amountBMin,'UniswapV2Router:INSUFFICIENT_B_AMOUNT');
(amountA,amountB)=(amountADesired,amountBOptimal);
}
else{
//按B的比例填充A的数量
//BB/AA=B/A-->BB=AA*(B/A)
uint amountAOptimal=UniswapV2Library.quote(amountBDesired,reserveB,reserveA);
assert(amountAOptimal<=amountADesired);
require(amountAOptimal>=amountAMin,'UniswapV2Router:INSUFFICIENT_A_AMOUNT');
(amountA,amountB)=(amountAOptimal,amountBDesired);
}
}
}
//返回值:A,B数量及得到的凭证数量
function addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
)external override ensure(deadline)returns(uint amountA,uint amountB,uint liquidity){
//返回值:A,B数量及得到的凭证数量
//调用_addLiquidity,计算需要打入的A,B数量
(amountA,amountB)=_addLiquidity(tokenA,tokenB,amountADesired,amountBDesired,amountAMin,amountBMin);
//获取pair的地址
address pair=UniswapV2Library.pairFor(factory,tokenA,tokenB);
//msg.sender往pair打入amount的A或者B
TransferHelper.safeTransferFrom(tokenA,msg.sender,pair,amountA);
TransferHelper.safeTransferFrom(tokenB,msg.sender,pair,amountB);
//pair给to发liquidity数量的凭证,并且pair增发liquidity的lp
liquidity=IUniswapV2Pair(pair).mint(to);
}
//添加池子,返回值是:token需要填充的数量,ETH需要填充的数量,liquidity
function addLiquidityETH(
address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
)external override payable ensure(deadline)returns(uint amountToken,uint amountETH,uint liquidity){
(amountToken,amountETH)=_addLiquidity(
token,
WETH,
amountTokenDesired,
msg.value,
amountTokenMin,
amountETHMin
);
//获取pair地址
address pair=UniswapV2Library.pairFor(factory,token,WETH);
//给pair转代币数量
TransferHelper.safeTransferFrom(token,msg.sender,pair,amountToken);
//调用weth的兑换方法,通过eth换weth,eth是公链币,weth是代币,但是它们兑换比例是1:1
IWETH(WETH).deposit{value:amountETH}();
assert(IWETH(WETH).transfer(pair,amountETH));
liquidity=IUniswapV2Pair(pair).mint(to);
//如果传入的eth数量,大于实际所需的eth数量,将剩余的eth返还给用户
if(msg.value>amountETH)TransferHelper.safeTransferETH(msg.sender,msg.value-amountETH);
}