cypto is the future!

在DeFi世界中,Dex(去中心化交易所)是最核心的一块,Uniswap是整个Dex的龙头,SushiSwap,PancakeSwap 等都是参考,甚至完全fork了Uniswap的整个产品逻辑和代码,也因此好多人也想部署快速部署一个属于自己的Uniswap,个人觉得也是很有必要的,通过自己从零搭建,一步一步完成,在这个过程可以清楚知道Uniswap整个项目工程的结构和产品逻辑,将来也能站在巨人的肩膀上,开发出自己的DeFi乐高!
前置说明:
本次部署是参考Uniswap V2的线上版本,同时结合催眠大师的教程总结来的。
本次部署的一些前置工作还需要自己提前准备,比如github账号,钱包,测试网代币水龙头,准备部署账户等
部署流程步骤:
从浏览器中下载合约源码
准备部署账户
使用remix编译部署合约
部署前端代码
安装依赖库
修改路由地址
将代码部署到Github Pages
生成自定义的token
自定义token导入Uniswap交易所
正文
从浏览器中下载合约源码
这次用的是线上版本
工厂合约 路由合约2 路由合约1是可选的,部署的流程是先部署工厂合约,然后将工厂合约的地址复制给路由合约2的构造函数。
准备部署账户
Uniswap的路由合约部署在以太坊主网和其他测试网的合约地址都是相同的,这样的结果就是无论前端切换到哪个网络,路由地址都是不变的。要想实现这个相同的地址的部署,我们需要准备一个全新的账户进行合约部署。全新的账户是指 部署之前的nonce值为0 .这个可以参考以太坊账户章节的合约账户来了解!
本次我们用的是Goerli测试网。
使用remix编译部署合约
本次部署我们用的是在线的remix编译器进行在线编译。
先准备一个全新的账户,并且通过Goerli水龙头接收测试币,每次是0.5个ETH,每24小时接收一次,没事接接水,关键时候可以解决大问题!
这个时候有人会问,为什么不用Truffle或者hardhat进行编译部署?其实是可以的,不过比较麻烦,主要是工厂合约和路由合约的编译版本不一致,导致在三方框架工具内编译起来比较麻烦,其次编译不是本文的主要目的。工具的使用后期会专门开一章进行讲解!
先将工厂合约copy下来进行编译。
其中红框的部分要注意和线上保持一致,istanbul EvmVersion和开启优化。

其次将路由合约进行编译,注意这几个红色箭头,Gas Limit改成9000000,这是因为路由文件太大,导致部署消耗的gas太大,会超出限制。其次,下面的构造函数中需要两个入参,一个是需要填写工厂合约的地址,另外一个是基于Goerli的WETH地址合约。因为ETH不是erc20的token,因此必须使用WETH作为交换媒介!
Goerli : 0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6

路由合约部署成功之后,将路由合约地址复制下来,替换React前端项目的主网的路由地址。该路由地址: 0x1762705FD51775b41701fAFCe8c90e4cF24e7a92
部署前端代码
克隆前端代码
git clone https://github.com/Uniswap/uniswap-interface.git
安装依赖库
cd uniswap-interface
yarn
初次安装编译的过程会比较长,在安装的时候可能会出现许多的问题,建议可以尝试多次重新编译安装或者去git上的issue上去查找响应问题的解答,在此就不再详细展开了。
编译和安装依赖成功之后,运行
yarn start --- 运行成功,同时会打开一个本地地址的Uniswap的前端界面
修改路由地址
用编辑器打开React前端项目工程,找到`
项目目录/uniswap-interface/src/constants/addresses.ts文件,找到V2_ROUTER_ADDRESS ,将值替换成上述编译好的路由合约地址变量
保存成功,重新运行即可 其实也看不出效果
yarn start

将代码部署到Github Pages
这一步的目的是安装部署一个线上可执行的环境。
首先先将git clone下来的项目中的.git目录全部删除掉。
rm -rf .git
其次初始化git,将Uniswap 前端代码添加到自己的项目仓库中
依次执行
git init
git remote add origin https://github.com/用户名/项目名.git
在前端项目中安装gh-pages模块,从而将前端代码部署到github.io,在前端代码的目录运行
yarn add gh-pages
安装成功之后,接下俩编译react和部署gh-pages,在前端代码的目录运行
yarn build
修改前端代码目录中的package.json
按照下图中的红色箭头依次修改
将homepage 对应的值改为
"homepage": "https://用户名.github.io/项目名称",//修改这里
同时在scripts,添加
"deploy": "gh-pages -d build" //添加这一行

完成之后,在前端代码目录运行依次运行以下命令
git add .
git commit -m ‘first commit‘
git push
yarn deploy ---- 在deploy运行的时候,首次部署会比较慢,如果出现错误,建议多次尝试部署命令
部署成功之后,打开浏览器输入地址 https://用户名.github.io/项目名称
就可以看到部署的效果页面了

生成自定义的token
自己可以尝试进行发行ERC20的代币,通过发行,添加流动性和Swap等步骤来更好的理解Uniswap的运行机制
我先把自定义发行token的代码贴下来,大家可以自行取用。
发币的过程很简单,就是发行token的合约继承ERC20就可以了。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0/contracts/token/ERC20/IERC20.sol
interface IERC20 {
function totalSupply() external view returns (uint);
function balanceOf(address account) external view returns (uint);
function transfer(address recipient, uint amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint amount) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint value);
event Approval(address indexed owner, address indexed spender, uint value);
}
其中IERC20可以用这个,也可以通过线上版本 Import导入就行
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import "./IERC20.sol";
contract ERC20 is IERC20 {
uint public totalSupply;
mapping(address => uint) public balanceOf;
mapping(address => mapping(address => uint)) public allowance;
string public name = "LICECoin";
string public symbol = "GOS";
uint8 public decimals = 18;
// constructor() public {
// mint(msg.sender, 100000000 * 10 ** 18);
// }
function transfer(address recipient, uint amount) external returns (bool) {
balanceOf[msg.sender] -= amount;
balanceOf[recipient] += amount;
emit Transfer(msg.sender, recipient, amount);
return true;
}
function approve(address spender, uint amount) external returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transferFrom(
address sender,
address recipient,
uint amount
) external returns (bool) {
allowance[sender][msg.sender] -= amount;
balanceOf[sender] -= amount;
balanceOf[recipient] += amount;
emit Transfer(sender, recipient, amount);
return true;
}
function mint(uint amount) external {
balanceOf[msg.sender] += amount;
totalSupply += amount;
emit Transfer(address(0), msg.sender, amount);
}
function burn(uint amount) external {
balanceOf[msg.sender] -= amount;
totalSupply -= amount;
emit Transfer(msg.sender, address(0), amount);
}
}
这是ERC20合约,其实可以直接在这个合约通过构造器直接创建,但是为了代码很好的分离,建议还是再单独建个MyToken合约
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.0.0/contracts/token/ERC20/ERC20.sol";
contract MyToken is ERC20 {
constructor(string memory name, string memory symbol) ERC20(name, symbol) {
// Mint 100 tokens to msg.sender
// Similar to how
// 1 dollar = 100 cents
// 1 token = 1 * (10 ** decimals)
_mint(msg.sender, 100000000 * 10**uint(decimals()));
}
}
以上就完成了一个子定义Token的发布过程。需要注意的是
在Remix中要切换到Goerli测试环境
账户中要有测试币
自定义token导入Uniswap交易所
将上述生成的token的合约保存下来,可以在etherscan.io上查看该币的相关信息
https://goerli.etherscan.io/token/0x7E9bc6163Dfdc63eb53E40DE41488BeC4C53372e
通过合约地址进行导入


之后可以通过添加流动性,在多个账户之间进行转账和Swap,同时注意看每次交换或者添加流动性和销毁流动性的时候,手续费是如何变换的。
总结
以上步骤就是整个搭建UniswapV2去中心化交易所Dex的流程步骤,其实步骤还是比较简单的,通过搭建过程,大家可以更好的了解DeFi中Dex的技术栈和工具,在进行测试的时候,也能更好的了解Uniswap V2产品的运行机制和逻辑。

在DeFi世界中,Dex(去中心化交易所)是最核心的一块,Uniswap是整个Dex的龙头,SushiSwap,PancakeSwap 等都是参考,甚至完全fork了Uniswap的整个产品逻辑和代码,也因此好多人也想部署快速部署一个属于自己的Uniswap,个人觉得也是很有必要的,通过自己从零搭建,一步一步完成,在这个过程可以清楚知道Uniswap整个项目工程的结构和产品逻辑,将来也能站在巨人的肩膀上,开发出自己的DeFi乐高!
前置说明:
本次部署是参考Uniswap V2的线上版本,同时结合催眠大师的教程总结来的。
本次部署的一些前置工作还需要自己提前准备,比如github账号,钱包,测试网代币水龙头,准备部署账户等
部署流程步骤:
从浏览器中下载合约源码
准备部署账户
使用remix编译部署合约
部署前端代码
安装依赖库
修改路由地址
将代码部署到Github Pages
生成自定义的token
自定义token导入Uniswap交易所
正文
从浏览器中下载合约源码
这次用的是线上版本
工厂合约 路由合约2 路由合约1是可选的,部署的流程是先部署工厂合约,然后将工厂合约的地址复制给路由合约2的构造函数。
准备部署账户
Uniswap的路由合约部署在以太坊主网和其他测试网的合约地址都是相同的,这样的结果就是无论前端切换到哪个网络,路由地址都是不变的。要想实现这个相同的地址的部署,我们需要准备一个全新的账户进行合约部署。全新的账户是指 部署之前的nonce值为0 .这个可以参考以太坊账户章节的合约账户来了解!
本次我们用的是Goerli测试网。
使用remix编译部署合约
本次部署我们用的是在线的remix编译器进行在线编译。
先准备一个全新的账户,并且通过Goerli水龙头接收测试币,每次是0.5个ETH,每24小时接收一次,没事接接水,关键时候可以解决大问题!
这个时候有人会问,为什么不用Truffle或者hardhat进行编译部署?其实是可以的,不过比较麻烦,主要是工厂合约和路由合约的编译版本不一致,导致在三方框架工具内编译起来比较麻烦,其次编译不是本文的主要目的。工具的使用后期会专门开一章进行讲解!
先将工厂合约copy下来进行编译。
其中红框的部分要注意和线上保持一致,istanbul EvmVersion和开启优化。

其次将路由合约进行编译,注意这几个红色箭头,Gas Limit改成9000000,这是因为路由文件太大,导致部署消耗的gas太大,会超出限制。其次,下面的构造函数中需要两个入参,一个是需要填写工厂合约的地址,另外一个是基于Goerli的WETH地址合约。因为ETH不是erc20的token,因此必须使用WETH作为交换媒介!
Goerli : 0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6

路由合约部署成功之后,将路由合约地址复制下来,替换React前端项目的主网的路由地址。该路由地址: 0x1762705FD51775b41701fAFCe8c90e4cF24e7a92
部署前端代码
克隆前端代码
git clone https://github.com/Uniswap/uniswap-interface.git
安装依赖库
cd uniswap-interface
yarn
初次安装编译的过程会比较长,在安装的时候可能会出现许多的问题,建议可以尝试多次重新编译安装或者去git上的issue上去查找响应问题的解答,在此就不再详细展开了。
编译和安装依赖成功之后,运行
yarn start --- 运行成功,同时会打开一个本地地址的Uniswap的前端界面
修改路由地址
用编辑器打开React前端项目工程,找到`
项目目录/uniswap-interface/src/constants/addresses.ts文件,找到V2_ROUTER_ADDRESS ,将值替换成上述编译好的路由合约地址变量
保存成功,重新运行即可 其实也看不出效果
yarn start

将代码部署到Github Pages
这一步的目的是安装部署一个线上可执行的环境。
首先先将git clone下来的项目中的.git目录全部删除掉。
rm -rf .git
其次初始化git,将Uniswap 前端代码添加到自己的项目仓库中
依次执行
git init
git remote add origin https://github.com/用户名/项目名.git
在前端项目中安装gh-pages模块,从而将前端代码部署到github.io,在前端代码的目录运行
yarn add gh-pages
安装成功之后,接下俩编译react和部署gh-pages,在前端代码的目录运行
yarn build
修改前端代码目录中的package.json
按照下图中的红色箭头依次修改
将homepage 对应的值改为
"homepage": "https://用户名.github.io/项目名称",//修改这里
同时在scripts,添加
"deploy": "gh-pages -d build" //添加这一行

完成之后,在前端代码目录运行依次运行以下命令
git add .
git commit -m ‘first commit‘
git push
yarn deploy ---- 在deploy运行的时候,首次部署会比较慢,如果出现错误,建议多次尝试部署命令
部署成功之后,打开浏览器输入地址 https://用户名.github.io/项目名称
就可以看到部署的效果页面了

生成自定义的token
自己可以尝试进行发行ERC20的代币,通过发行,添加流动性和Swap等步骤来更好的理解Uniswap的运行机制
我先把自定义发行token的代码贴下来,大家可以自行取用。
发币的过程很简单,就是发行token的合约继承ERC20就可以了。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0/contracts/token/ERC20/IERC20.sol
interface IERC20 {
function totalSupply() external view returns (uint);
function balanceOf(address account) external view returns (uint);
function transfer(address recipient, uint amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint amount) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint value);
event Approval(address indexed owner, address indexed spender, uint value);
}
其中IERC20可以用这个,也可以通过线上版本 Import导入就行
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import "./IERC20.sol";
contract ERC20 is IERC20 {
uint public totalSupply;
mapping(address => uint) public balanceOf;
mapping(address => mapping(address => uint)) public allowance;
string public name = "LICECoin";
string public symbol = "GOS";
uint8 public decimals = 18;
// constructor() public {
// mint(msg.sender, 100000000 * 10 ** 18);
// }
function transfer(address recipient, uint amount) external returns (bool) {
balanceOf[msg.sender] -= amount;
balanceOf[recipient] += amount;
emit Transfer(msg.sender, recipient, amount);
return true;
}
function approve(address spender, uint amount) external returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transferFrom(
address sender,
address recipient,
uint amount
) external returns (bool) {
allowance[sender][msg.sender] -= amount;
balanceOf[sender] -= amount;
balanceOf[recipient] += amount;
emit Transfer(sender, recipient, amount);
return true;
}
function mint(uint amount) external {
balanceOf[msg.sender] += amount;
totalSupply += amount;
emit Transfer(address(0), msg.sender, amount);
}
function burn(uint amount) external {
balanceOf[msg.sender] -= amount;
totalSupply -= amount;
emit Transfer(msg.sender, address(0), amount);
}
}
这是ERC20合约,其实可以直接在这个合约通过构造器直接创建,但是为了代码很好的分离,建议还是再单独建个MyToken合约
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.0.0/contracts/token/ERC20/ERC20.sol";
contract MyToken is ERC20 {
constructor(string memory name, string memory symbol) ERC20(name, symbol) {
// Mint 100 tokens to msg.sender
// Similar to how
// 1 dollar = 100 cents
// 1 token = 1 * (10 ** decimals)
_mint(msg.sender, 100000000 * 10**uint(decimals()));
}
}
以上就完成了一个子定义Token的发布过程。需要注意的是
在Remix中要切换到Goerli测试环境
账户中要有测试币
自定义token导入Uniswap交易所
将上述生成的token的合约保存下来,可以在etherscan.io上查看该币的相关信息
https://goerli.etherscan.io/token/0x7E9bc6163Dfdc63eb53E40DE41488BeC4C53372e
通过合约地址进行导入


之后可以通过添加流动性,在多个账户之间进行转账和Swap,同时注意看每次交换或者添加流动性和销毁流动性的时候,手续费是如何变换的。
总结
以上步骤就是整个搭建UniswapV2去中心化交易所Dex的流程步骤,其实步骤还是比较简单的,通过搭建过程,大家可以更好的了解DeFi中Dex的技术栈和工具,在进行测试的时候,也能更好的了解Uniswap V2产品的运行机制和逻辑。

Subscribe to cyptoJune
Share Dialog
Share Dialog
<100 subscribers
<100 subscribers
No activity yet