首页 > 编程语言 >Uniswap V2源码解读

Uniswap V2源码解读

时间:2024-03-31 09:01:18浏览次数:40  
标签:const log console V2 源码 Uniswap new uniswap

Uniswap是一个开源的去中心化的交易所,在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 = ??? WETH
  console.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_KEY's Address, 或者随便一个地址用来接收
  const deadline = Math.floor(Date.now() / 1000) + 60 * 20 // 20 minutes from the current Unix time
  const 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);
 
}

 

简介引用: https://www.coindesk.com/business/2021/02/04/what-is-uniswap-a-complete-beginners-guide/

uniswap业务概念参考: https://juejin.cn/post/7178857641421045820

如何使用uniswap SDK: https://kaai.dev/learn-uniswap-v2-sdk

如何实现去中心化交易所: https://pixelplex.io/blog/how-to-build-decentralized-crypto-exchange/

标签:const,log,console,V2,源码,Uniswap,new,uniswap
From: https://www.cnblogs.com/johnchow/p/18053185

相关文章

  • 你真的了解回调函数吗?(文章最后放置源码)
    一、什么是回调函数简单来说就是通过函数指针调用的函数。复杂一些呢就是说将函数的指针(地址)作为参数传递给另外一个函数使用,当这个指针被用来调用其指向的函数的时候被调用的函数就是回调函数。二、回调函数怎么使用1、在学习回调函数之前我们是如何进行运算的我们来看下......
  • 基于Android的校园二手交易平台系统应用设计与实现(论文+源码)
    安卓AndroidStudio校园二手交易平台app源码带javaweb后台Springbootmybatis框架数据库mysql,非常适合学习使用。包含项目报告,接近9000字数文档(项目介绍、需求分析、系统设计、关键技术实现、数据库表设计、主要模块关键代码、系统测试、成果展示);App基于AndroidStudio开......
  • 基于Android的IM即时通讯聊天系统应用设计与实现(论文+源码+讲解视频)
    安卓AndroidStudio聊天app源码带java后台Nettymybatis框架数据库mysql,非常适合学习使用。基于Netty实现IM即时通讯开发120分钟代码讲解视频包含项目报告,接近22000字数文档(绪论、项目相关技术、项目需求分析、项目系统设计、数据库设计、系统功能实现、系统测试、结论及参......
  • 【即插即用】SE通道注意力机制(附源码)
    原文地址:Squeeze-and-ExcitationNetworks源码地址:GitHub-hujie-frank/SENet:Squeeze-and-ExcitationNetworks摘要简介:卷积神经网络建立在卷积操作的基础上,它通过融合局部感受野内的空间信息和通道信息来提取有用的特征。近年来,为了提高网络的表示能力,多种方法显示出......
  • 2024年3月全新超强版本itvboxfast影视APP源码 TV+手机双端源码 新增超多功能 tvbox二
    不要拿烂大街的版本比较,没有可比性,修复大街版本所有bug,增加超多功能。这个版本堪称如意界最强,后台支持某条线路、直播指定账号输入密码观看,VIP会员专用线路,去插播视频的广告,TV端修复套餐金额设置小数点闪退,更改公告显示样式,首页轮播图新增支持显示视频,TV端和手机端分别设......
  • 2023最新293TV v6.2 APP源码 神马TV影视APP源码可对接易支付 修复搜索附安装教程
    神马TV影视APP源码可对接易支付修复搜索附安装教程源码简介2023最新版本293TV、神马tv源码6.2版本修复首字母拼音搜索支持所有易支付解决6.2版本通病自动巡检删除后台文件JSON和api解析后台随意设置总共有5套后台:中控后台,会员后台,苹果CMS后台,反馈后台,解析后台,会员......
  • Go 源码之 Chan
    Go源码之chango源码之chan-Jxy博客一、总结chan提供了一种在goroutine之间进行数据交换和同步的方式。通道可以用于控制并发访问和共享数据,从而减少竞态条件和死锁问题,并且可以自然地处理异步事件和信号。如果你的应用程序需要在goroutine之间传递数据或消息,那......
  • C#实现窗体弹出的三种方式(附完整源码)
    C#实现窗体弹出的三种方式以下是C#实现窗体弹出的三种方式的完整源码:使用Show方法弹出窗体:usingSystem;usingSystem.Windows.Forms;namespaceWindowsFormsApp1{publicpartialclassForm1:Form{publicForm1(){......
  • 32万7950=假设一个120kw的直流充电桩,请问根据常规使用率和电价,一年之内它能赚取多少收
    为了估算一个120kW直流充电桩一年的收入,我们需要做一些假设。以下是一些可能的假设值:充电费率:假设每千瓦时(kWh)电能的价格为0.5元至1.5元不等,具体取决于地区和电力供应商。常规使用率:假设充电桩每天工作10小时,即一年工作天数为365天。运营时间:假设充电桩全年无休,每天24......
  • 【STM32项目】基于STM32多传感器融合的新型智能导盲杖设计(完整工程资料源码)
    基于STM32多传感器融合的新型智能导盲杖设计演示效果基于stm32智能盲杖  前言:      目前,中国盲人数量已突破两千万大关,而城市盲道设计不合理、盲道被非法侵占等危害盲人出行安全的问题屡禁不止[1-3]。随着科技发展,智能盲杖不断涌现,但这些智能盲杖并不智能[4,5]......