做wordpress 下载站,vps一定要Wordpress吗,中国建设网站,寿光市建设局网站Uniswap是一个开源的去中心化的交易所#xff0c;在github上面有以下重要仓库#xff1a;
uniswap-v2-core#xff1a; 币对池pair的核心智能合约。这个repository包含了Uniswap的币对池pair的所有核心逻辑#xff0c;增加流动性、减少流动性等。uniswap-v2-periphery在github上面有以下重要仓库
uniswap-v2-core 币对池pair的核心智能合约。这个repository包含了Uniswap的币对池pair的所有核心逻辑增加流动性、减少流动性等。uniswap-v2-periphery这个repository包含了Uniswap V3的所有周边智能合约。这些合约提供了与核心合约交互的附加功能例如多次跨路径交易和非fungible流动性。uniswap-interface这是Uniswap的主要前端接口。它是一个开源的Web应用程序允许用户直接与Uniswap协议进行交互可以直接用于做客户端uniswap-v3-sdk这些开发工具包用于帮助开发者构建自己的客户端应用程序从而与 Uniswap 智能合约进行交互。uniswap-v3-subgraph这是Uniswap V3的子图项目用于从以太坊区块链上获取和索引 Uniswap V3 的数据。开发者可以通过 GraphQL API 从子图中查询 Uniswap 的数据以便在自己的应用程序中使用。 一、AMM交易机制
不同于传统订单薄的交易模式 uniswap交易使用的是恒定乘积公式的自动做市商模式。即交易前后池子内一对代币的乘积保持不变。 在uniswap v2中每次会收取0.3%的手续费即p 0.003,这笔手续费从交易者的x中扣除分发给流动性提供者。因此只有x *1-p的A数量来兑换y数量的B。剩下p * x会作为手续费被添加到池子中此时上面的等式会变为 二、 合约设计 RouterContract路由合约对外提供api的合约。主要包括注入流动性、移除流动性、兑换等 addLiqudity(token0, token1, amount0, amount1)币对(token0和token1)的金额进过计算后会转入到pair的地址里 pair合约同时会计算出持有代币转入到msg.sender地址里。removeLiqudity(token0, token1, liqudity)先把msg.sender地址里的pair持有代币转回给pair地址 调用pair地址的burn方法按token0、token1总量比例得到各自的amount把token0和token1的转amount0和amount1到msg.sender地址swapToken UniswapV2Library工具库合约主要提供根据factory地址计算池地址、币对token总量等UniswapV2Factory币对工厂合约主要在合约内运行时部署若干新的UniswapPair合约实例并得到地址UniswapPair币对的ERC20代币合约。每个部署实例都对应1个币对币对供应量增加它会mint增加总量反之会burn减少总量 三、SDK设计
Uniswap SDK 是一个同构 (Isomorphic) 的库既可以在客户端使用也可以在服务端使用。SDK不能代表用户执行或发送交易它提供了实用的类和函数帮助计算出安全地与 Uniswap 交互所需要的数据。
Token用于构建token实例Pair获取Pair相关信息Route创建交易路径。 前端计算得出比如[token0, token1]是可以直接作为交易路径还是要因为没有这个币对池要用[token0, token2], [token2, token0]作交易路径Trade构建交易且用于计算出交易的数据比如期望交易输出Percent/Fraction 百分比、有理数等 都是数字类抽象帮助计算的
// swapExactETHForTokens
import { ChainId, Token, Fetcher, Pair, TokenAmount, Route, Trade, TradeType, Percent } from uniswap/sdk
import { ethers } from ethers
import dotenv/config// 构建client包括provider、account
const rpcurl https://rinkeby.infura.io/v3/${process.env.INFURA_PROJECT_ID};
const provider new ethers.providers.JsonRpcProvider(rpcurl);
const signer new ethers.Wallet(process.env.PRIVATE_KEY);
const account signer.connect(provider);// 构建token0、token1
const WETH new Token(ChainId.RINKEBY, 0xc778417E063141139Fce010982780140Aa0cD5Ab, 18);
const LINK new Token(ChainId.RINKEBY, 0x01BE23585060835E02B77ef475b0Cc51aA1e0709, 18);const uniV2ABI [function swapExactETHForTokens(uint amountOutMin, address[] calldata path, \address to, uint deadline) external payable returns (uint[] memory amounts)];
const uniswapContract new ethers.Contract(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D, uniV2ABI, account);
const run async () {// 获取币对池信息const pair await Fetcher.fetchPairData(LINK, WETH, provider);// 构建交易路径const route new Route([pair], WETH);console.log(route.midPrice.numerator.toString());console.log(route.midPrice.denominator.toString());console.log(WETH-LINK, route.midPrice.toSignificant(6));// 1 LINK ??? WETHconsole.log(route.midPrice.invert().numerator.toString());console.log(route.midPrice.invert().denominator.toString());console.log(LINK-WETH, route.midPrice.invert().toSignificant(6));// 构建交易const trade new Trade(route, new TokenAmount(WETH, ethers.utils.parseEther(0.003)), TradeType.EXACT_INPUT);console.log(trade.executionPrice.toSignificant(6));const slippageTolerance new Percent(50, 10000);const amountOutMin trade.minimumAmountOut(slippageTolerance).raw;const path [WETH.address, LINK.address];const to 0x... // PRIVATE_KEYs Address, 或者随便一个地址用来接收const deadline Math.floor(Date.now() / 1000) 60 * 20 // 20 minutes from the current Unix timeconst value trade.inputAmount.raw;console.log(value.toString())// 调用合约方法进行兑换交易const tx await uniswapContract.swapExactETHForTokens(amountOutMin.toString(), path, to, deadline, {value: value.toString(),// maxFeePerGas: ethers.utils.parseUnits(2,gwei),// maxPriorityFeePerGas: ethers.utils.parseUnits(2,gwei),});console.log(Transaction hash: ${tx.hash});const receipt await tx.wait();console.log(receipt);}