30分钟搭建Defi Swap Dapp(如Pancakeswap,Uniswap)含项目原理,源码和源码分析

前言

提示:本文以Uniswap为案例进行项目分析。旨在于区块链技术分享,相互学习探讨为目的,不作任何投资建议,读者使用本文技术做违法行为与本人无关。

一、Uniswap介绍

1.中心化交易所与去中心化交易所的异同

1.1.中心化交易优缺点

a.优点:

交易速度快

用户使用门槛低,不用自己管理私钥

有otc机制

b.缺点:

可以对价格进行操控

用户的资产被撑控,交易所有可能封停,也有可能跑路

用户信息被暴露

1.2.去中心化交易优缺点

a.优点:

身份信息保密

交易数据公开透明

b.缺点:

门槛高,用户必须先持有一个种币资产

价格高于中心化交易所

2.架构分析

Uniswap是一种自动流动性协议,由恒定乘积公式提供支持,并在以太坊区块链上的不可升级智能合约系统中实施。它消除了对受信任的中介机构的需求,从而优先考虑了权力下放,审查制度抵抗和安全性。 Uniswap是根据GPL许可的开源软件。

每个Uniswap智能合约或一对智能合约都管理由两个ERC-20代币的储备组成的流动资金池。

任何人都可以通过存入等值的基础代币来换取池代币,从而成为池的流动性提供者(LP)。

这些代币跟踪总储备中按比例分配的LP份额,

并可随时赎回相关资产。

货币对充当自动做市商,只要保留“恒定乘积”的公式,就随时准备接受另一种代币。该公式 最简单地表示为x * y = k,它表示交易不得更改货币对的准备金余额(x和y)的乘积(k)。 因为k从交易的参考框架保持不变,所以通常将其称为不变式。此公式具有令人满意的特性, 即相对于较小的交易,较大的交易(相对于储备金)以指数级的差价执行。

实际上,Uniswap对交易收取0.30%的费用,该费用会添加到准备金中。结果,每笔交易实 际上增加了k。这是对LP的支出,这是在LP燃烧其池令牌以提取其总储备中的一部分时实现 的。将来,此费用可能会降低到0.25%,其余的0.05%作为协议范围的费用保留。

由于两对资产的相对价格只能通过交易进行更改,因此Uniswap价格与外部价格之间的差异 会产生套利机会。这种机制确保Uniswap价格始终趋向于结算价。

3.uniswap中的恒定乘积做市

公式: K= XY

同时加一个值或减一个值,来保证最后的 值不变 (X+a)(Y-b) = K

这里 , 则代表一个交易对,如 USDT<=>ETH

最初的价格由最开始添加流动性来决定,但价格如果不合理与外界交易所偏差过大时,会被套 利抹平,最终趋向于合理价。

本节可以参考《手把手教你搭建去中心化交易所》课程- lesson 1-《uiswap介绍》


二、通过sdk使用uniswap各项功能

准备工作

1. 安装好nodejs环境&安装npm

(提示:由于编译的代码所需的版本不同,本文分享的源码Node.js _v>15,用到的npm指令如下:)
同时可以参考往前的文章《npm常用命令详解

安装相关命令:
npm install <package-name>: 安装指定的包。
npm install <package-name>@<version>: 安装指定版本的包。
npm install: 安装项目package.json文件中列出的所有依赖项。
npm install --global <package-name>: 全局安装指定的包。

更新相关命令
npm update <package-name>: 更新指定的包到最新版本。
npm update: 更新package.json中列出的所有依赖项。
npm outdated: 检查项目中哪些包有新版本可用。

配置相关命令
npm config list: 显示当前npm配置。
npm config set <key> <value>: 设置npm配置参数。
npm config get <key>: 获取指定的npm配置参数值。
npm config delete <key>: 删除指定的npm配置参数。

2. 准备好vscode编辑器 

Visual Studio Code(VS Code)是一款免费、开源且跨平台的代码编辑器,支持多种操作系统和设备。对于各设备的下载,您可以参考以下步骤:

  1. 访问VS Code的官方网站:https://code.visualstudio.com/。
  2. 在网站首页,您会看到针对不同操作系统的下载选项,包括Windows、macOS和Linux。

请注意,以上步骤是一般性的指导,具体步骤可能因设备和操作系统版本的不同而有所差异。在下载和安装过程中,如果遇到任何问题,您可以参考VS Code官方文档或向社区寻求帮助。此外,为了确保您下载的是最新版本的VS Code,请务必从官方网站进行下载,避免从非官方渠道下载,以免遭遇恶意软件或病毒的风险。

3.熟悉部分区块链Web3调用库的知识

如果有兴趣可以详细阅读一下文档资料,对区块链应用技术非常有用。下面是我梳理了一下大家的求知方向,建议大家可以专研。

1. 获取token信息

2. 获取配对合约

3. 获取对应token价格

4. 生成交易

5. 发送交易

sdk文档 https://uniswap.org/docs/v2
etherjs https://docs.ethers.io/v5/
alchemy https://dashboard.alchemyapi.io 

本节可以参考《手把手教你搭建去中心化交易所》课程- lesson 2-《通过sdk使用uniswap各项功能》


三、合约部署

• uniswap-v2-core 核心合约
• uniswap-v2-periphery 周边合约
• uniswap-interface web界面

开发环境

• hardhat

• 增加typescript支持 https://hardhat.org/guides/typescript.html

部署

1.整理合约,将两个合约合并在一起

2.修改代码,部署

   2.1. 编译版本号不统一问题

   2.2. Route02合约过大的问题

本节可以参考《手把手教你搭建去中心化交易所》课程- lesson 3-《合约部署》


四、兑换流程源码分析

关键API

swapExactTokensForTokens

使用确定数量的TokenA来换取TokenB

function swapExactTokensForTokens(

uint amountIn,

uint amountOutMin,

address[] calldata path,

address to,

uint deadline

) external returns (uint[] memory amounts);

swapTokensForExactTokens


 

使用最大量的TokenA来换取确定数量的TokenB

function swapTokensForExactTokens(

 uint amountOut,

 uint amountInMax,

 address[] calldata path,

 address to,

 uint deadline

) external returns (uint[] memory amounts);

还有一些类似的Api,作用都差不太多,可以举一反三 swapExactTokensForTokensSupportingFeeOnTransferTokens 这种是支持通缩Token
...

关键流程

本节可以参考《手把手教你搭建去中心化交易所》课程- lesson 4-《兑换流程源码分析》


五、添加流动性流程分析

关键API

addLiquidity
添加流动性

function addLiquidity(
 address tokenA,
 address tokenB,
 uint amountADesired,
 uint amountBDesired,
 uint amountAMin,
 uint amountBMin,
 address to,
 uint deadline
 ) external virtual override ensure(deadline) returns (uint amountA, uint amountB, uint liquidity)

removeLiquidity
移除流动性

function removeLiquidity(
 address tokenA,
 address tokenB,
 uint liquidity,
 uint amountAMin,
 uint amountBMin,
 address to,
 uint deadline
 ) public virtual override ensure(deadline) returns (uint amountA, uint amountB)
removeLiquidityETHSupportingFeeOnTransferTokens

关键流程

本节可以参考《手把手教你搭建去中心化交易所》课程- lesson 5-《添加流动性流程分析》


六、前端界面部署

准备工作

1. 下载整合好的uniswap合约代码《手把手教你搭建去中心化交易所》课程- 代码包

合约代码在“contracts”文件夹中

2. 下载uniswap前端代码《· uniswap-interface web界面

编译合约

注意 .env 文件需要自己填写

yarn hardhat run scripts/uniswap.ts --network kovan

记下编译出来router地址

修改web

1. 修改router地址

src/constants/index.ts
ROUTER_ADDRESS

2. 修改配置文件为kovan环境

.env

3. 修改sdk中的factory和initcode

node_modules下面有个@uniswap/sdk/dist/constants.d.ts和sdk.esm.js

4. 启动

yarn start

5. 部署

yarn build

安装yarn可以参考《一文学会yarn安装与配置》   
本节可以参考《手把手教你搭建去中心化交易所》课程- lesson 6-《前端界面部署》    


七、测试 

以上操作如没出问题,直接 npm run 就可以进入测试页面。 


八、实操

熟悉以上内容,原理,大家可以用我提供的BSC链的SWAP项目作为练习。

下载链接:《bsc swap simple code》如链接失效可以直接评论区或私信。    

1.安装node.js

Node.js 可以在多种操作系统上运行,包括 Windows、Linux 和 macOS。自己根据设备自行下载并运行安装,配置环境变量。(提示下,上面代码使用的是node.js v16)

1.1.安装npm管理器

npm install <package-name>: 安装指定的包
npm install <package-name>@<version>: 安装指定版本的包。
npm install: 安装项目package.json文件中列出的所有依赖项。
npm install --global <package-name>: 全局安装指定的包。

不懂安装的可以看《npm常用命令详解

1.2.安装yarn 

在命令行中运行以下命令:npm install -g yarn。这个命令会全局安装Yarn,使得您可以在任何地方使用Yarn命令。参考《一文学会yarn安装与配置

cd <package-name>  yarn install

yarn _v1.22.17

1.3.启动项目 

$ react-scripts start

如果提示 npx browserslist@latest --update-db 这意味着你当前的 caniuse-lite 数据库版本已经过时了,因此你可能无法获取到最新的浏览器兼容性数据。直接输入:

npx browserslist@latest --update-db

这个命令会利用 npx 运行最新版本的 browserslist 工具,并使用 --update-db 标志来更新 caniuse-lite 数据库。确保你在运行这个命令时有足够的权限(在Unix系统上可能需要使用 sudo,如果你全局安装了 npx),并且你的网络连接是稳定的,以便能够成功地从 npm 注册表下载最新的数据。

如无意外,项目会自动打开你电脑默认的浏览器,画面如下,代表你的环境已经没问题了!👍

2.修改前端UI

这部分我就不细讲了,html,CSS,JS...想怎么改就怎么改。不熟悉的可以在CSDN搜索html网页制作的相关教程,以后我也会对该技术内容作分享。

网页UI在以下文件夹

.../public

 3.修改/编译/部署合约

编辑器打开.\src\constants\index.ts 
复制合约地址:0x10ED43C718714eb63d5aA57B78B54704E256024E

打开BSCSCAN浏览器(以后再分享几篇区块链浏览器的相关知识,现在为了正题凑合一下),搜索刚复制的合约地址:0x10ED43C718714eb63d5aA57B78B54704E256024E 复制合约的开源代码

复制路由合约&工厂合约的开源代码

预防大家“网速不好”我还是把合约代码粘贴在这里吧,代码中已有对应的注析,大家可以参考“章节四”进行参数的修改。

路由合约代码
/**
 *Submitted for verification at BscScan.com on 2020-09-03
*/

/**
 *Submitted for verification at Bscscan.com on 2020-09-03
*/

pragma solidity ^0.4.18;

contract WBNB {
    string public name     = "Wrapped BNB";
    string public symbol   = "WBNB";
    uint8  public decimals = 18;

    event  Approval(address indexed src, address indexed guy, uint wad);
    event  Transfer(address indexed src, address indexed dst, uint wad);
    event  Deposit(address indexed dst, uint wad);
    event  Withdrawal(address indexed src, uint wad);

    mapping (address => uint)                       public  balanceOf;
    mapping (address => mapping (address => uint))  public  allowance;

    function() public payable {
        deposit();
    }
    function deposit() public payable {
        balanceOf[msg.sender] += msg.value;
        Deposit(msg.sender, msg.value);
    }
    function withdraw(uint wad) public {
        require(balanceOf[msg.sender] >= wad);
        balanceOf[msg.sender] -= wad;
        msg.sender.transfer(wad);
        Withdrawal(msg.sender, wad);
    }

    function totalSupply() public view returns (uint) {
        return this.balance;
    }

    function approve(address guy, uint wad) public returns (bool) {
        allowance[msg.sender][guy] = wad;
        Approval(msg.sender, guy, wad);
        return true;
    }

    function transfer(address dst, uint wad) public returns (bool) {
        return transferFrom(msg.sender, dst, wad);
    }

    function transferFrom(address src, address dst, uint wad)
    public
    returns (bool)
    {
        require(balanceOf[src] >= wad);

        if (src != msg.sender && allowance[src][msg.s
  • 33
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HongYingClub

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值