Uniswap/v2-core使用及其交易流程

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 = ??? 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_KEY's 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);}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/460809.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

萤石私有化设备视频平台EasyCVR视频融合平台如何构建农业综合监控监管系统?

现代农业的迅速发展中,集成监控管理系统已成为提高农业生产效率和优化管理的关键工具。萤石私有化设备视频平台EasyCVR,作为一个具有高度可扩展性、灵活的视频处理能力和便捷的部署方式的视频监控解决方案,为农业监控系统的建设提供了坚实的技…

如何在小红书发布笔记时显示外地IP地址

小红书平台在发布笔记时显示IP地址可能是由于网络爬虫或者某些技术手段抓取数据时所导致的。为了保护用户隐私和安全,显示外地IP地址,可以尝试以下几种方法: 1.检查发布环境: 确保你是在一个安全、可信的网络环境下发布笔记&…

数据结构——单链表详解

博客ID:LanFuRenC系列专栏:C语言重点部分 C语言注意点 C基础 Linux 数据结构 C注意点 声明等级:黑色->蓝色->红色 欢迎新粉加入,会一直努力提供更优质的编程博客,希望大家三连支持一下啦 目录 1.链表的概念…

奥数与C++小学四年级(第十二题 装礼盒)

参考程序代码&#xff1a; #include <iostream> #include <vector> #include <algorithm>using namespace std;int main() {// 各种颜色宝石的数量vector<int> gems {11, 22, 33, 44, 55, 66, 77};int totalBoxes 0;while (true) {// 对宝石数量进行…

Zookeeper 对于 Kafka 的作用是什么?

大家好&#xff0c;我是锋哥。今天分享关于【Zookeeper 对于 Kafka 的作用是什么&#xff1f;】面试题&#xff1f;希望对大家有帮助&#xff1b; Zookeeper 对于 Kafka 的作用是什么&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 ZooKeeper 在 Kafka…

基于SSM学生竞赛模拟系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;公告信息管理&#xff0c;试题管理&#xff0c;论坛交流&#xff0c;试卷管理&#xff0c;系统管理 前台账号功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;公告…

pip使用

pip全称pip install package,是python第三方包sitepackage管理的工具&#xff0c;安装&#xff0c;卸载第三方包。安装python时可以选择安装pip&#xff0c;或自己安装pip 查看pip是否安装&#xff1a;pip --version 安装pip &#xff1a;pip python -m pip install --upgrade…

Netron:神经网络模型可视化工具指南【全网最详细】

目录 Netron初印象 Netron 功能是什么&#xff1f; Netron 的来源 支持的模型文件格式 如何使用 Netron 打开和查看模型文件&#xff1f; 要掌握哪些知识才能看懂模型结构&#xff1f; 模型结构解释 part1 part2 part3 part4 part5 各节点解释说明 起始和终止节点…

ComfyUI - ComfyUI 工作流中集成 SAM2 + GroundingDINO 处理图像与视频 教程

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/143359538 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 SAM2 与…

阿里云物联网的通信方式

阿里云物联网通信的两种方式&#xff0c;一个是物模型&#xff08;分为服务&#xff0c;事件&#xff0c;属性此篇文章只讲解物模型中的服务和属性用法&#xff09;&#xff0c;一个是自定义topic&#xff08;要另外设置数据流转&#xff09; 1.使用产品内的功能定义&#xff0…

mysql5.7.44 arm 源码编译安装

一、&#xff1a;下载源码&#xff1a;mysql官网&#xff1a;MySQL :: MySQL Downloads #####下载mysql安装包 &#xff1a; 网址&#xff1a;https://www.mysql.com/ 可在页面下载后上传或直接下载。 官网地址首页&#xff0c;拉到最底部&#xff0c;找到社区版本下载&#xf…

BatchNorm推理阶段和Conv合并

BatchNorm推理阶段和Conv合并 本文全文来自&#xff1a; https://www.cnblogs.com/xiaxuexiaoab/p/16422640.html。 只只作为自己的复习使用&#xff0c;不作他用。 BN层作用 批量归一化&#xff08;Batch Normalization&#xff0c;BN&#xff09;在深度学习中常放在卷积层之…

第二十章 Vue组件通信之父子通信

目录 一、引言 二、组件关系分类 三、组件通信的解决方案 3.1. 父子通信流程图 3.2. 父组件通过 props 将数据传递给子组件 3.2.1. 代码App.vue 3.2.2. 代码MySon.vue 3.3. 子组件利用 $emit 通知父组件修改更新 ​编辑3.3.1. 代码App.vue 3.3.2. 代码MySon.vue 3…

对话瀚荃:为何欧美拟统一采用USB-C充电接口?

【哔哥哔特导读】英国、美国等地都准备统一电气设备充电标准&#xff0c;USB-C接口为何成为业界首选?选择USB-C连接器&#xff0c;又有什么注意事项? 近期&#xff0c;有消息指出英国、美国等地均启动了关于电气设备充电标准的咨询活动&#xff0c;希望听取制造商、进口商、…

如何解决RabbitMQ消息的重复消费问题

什么情况下会导致消息的重复消费——在消费者还没成功发送自动确认机制时发生&#xff1a; 网络抖动消费者挂了 解决方案 每条消息设置一个唯一的标识id幂等方案&#xff1a;【Redis分布式锁、数据库锁&#xff08;悲观锁、乐观锁&#xff09;】 面试官&#xff1a;如何解决…

vue中el-table显示文本过长提示

1.el-table设置轻提示:show-overflow-tooltip“true“&#xff0c;改变轻提示宽度

Couldn‘t apply path mapping to the remote file.

Couldn’t apply path mapping to the remote file. /s6home2/zjw524/projects/seq2seq/code/deepnmtpycharm/deepNmt/code/deepNmtPycharm/deepNmt/model/Deep_NMT_Model.py can’t be found in project. You can continue debugging, but without the source. To fix that yo…

Tech Talk: 浅谈AI浪潮下的计算型存储SSD

引言 近年来&#xff0c;AI应用态势迅猛增加&#xff0c;对计算侧的算力和内存提出了更高的要求。GPU、HBM这些高性能高密计算部件和内存部件&#xff0c;在AI计算场景中作为必需品&#xff0c;成为市场热点。业界也在讨论能否把计算侧的业务卸载到存储侧&#xff0c;称为计算…

华为配置 之 STP

目录 简介&#xff1a; STP&#xff1a; RSTP: 如何改变根网桥&#xff1a; &#xff08;1&#xff09;改变优先级&#xff1a; &#xff08;2&#xff09;改变root: 各端口的状态&#xff1a; 总结&#xff1a; 简介&#xff1a; STP&#xff08;Spanning Tree Protoco…