# DeFi交易龙头之Uniswap：V2(核心合约-工厂合约)

By [cyptoJune](https://paragraph.com/@cyptojune) · 2022-02-18

---

在DeFi赛道中，Dex是整个DeFi乐高极其关键的模组，Uniswap 又是整个Dex领域的龙头，而SushiSwap，PancakeSwap等也是fork了Uniswap的开源代码。**它的创新之处就是舍弃了传统订单薄的撮合方式，采用了流动性+恒定乘积共识算法来为不同资产和交易对提供及时报价和兑换服务**。

接下来的系列文章，我会分成系列文章来刨析UniswapV2的产品架构和合约代码，提供诸如手续费的手续以及分配机制的实现，注入流动性算出返回LP Token等。

系列文章参考了诸如youtube -崔棉大师 课程--去中心化交易所等13节课程讲解以及youtube -@mrblock 區塊先生 等诸多up主的无私讲解。

Uniswap V2的产品模块拆分了很多项目模块，主要包括以下：

*   uniswap-interface
    
*   uniswap-v2-sdk
    
*   uniswap-sdk-core
    
*   uniswap-info
    
*   uniswap-v2-subgraph
    
*   uniswap-v2-core
    
*   uniswap-v2-periphery
    
*   uniswap-lib
    
    前三个是前端App项目，提供交易的模块。
    
    uniswap-interface项目模块是放置前端页面以及展示应用的功能。
    
    Uniswap-v2-sdk和Uniswap-sdk-core是作为SDK存在的。uniswap-interface会引用v2-sdk和sdk-core，通过uniswap/v2-sdk和uniswap/sdk-core的方式引入到需要使用的TS文件中。
    
    Uniswap-inerface最新代码是跟线上是同步的，即是集成了v3版本。如果只想部署v2版本前端，可以找出历史版本check出来进行部署。
    
    Uniswap-info则是**Uniswap Analytics** 项目，业务数据主要是从 Subgraph 读取。_uniswap-v2-subgraph_ 则是 Subgraph 项目。
    
    最后三个则是合约项目了，**uniswap-v2-core** 就是核心合约的实现； **uniswap-v2-periphery** 则提供了和 UniswapV2 进行交互的外围合约，主要就是路由合约；**uniswap-lib** 则封装了一些工具合约。
    
    本篇文章我们先讲解**uniswap-v2-core**核心合约的实现。
    
*   **UniswapV2Factory.sol**：工厂合约
    
*   **UniswapV2Pair.sol**：配对合约
    
*   **UniswapV2ERC20.sol**：LP Token 合约
    
    **配对合约管理着流动性资金池，不同币对有着不同的配对合约实例**，比如USDT-WETH这一币对，就对应一个配对合约的实例，DAI-WETH 又对应另一个配对合约实例。
    
    LP Token合约则是用户往资金池注入流动性的一种凭证，也成为流动性代币。当用户往某个币对合约里转入两种token,即是添加流动性，那么就可以得到配对合约返回的LP Token，享受手续费分成收益。
    
    工厂合约则是用来部署配对合约的，通过工厂合约的createPair()函数来创建新的配对合约实例。
    
    三个合约的关系：
    

![](https://storage.googleapis.com/papyrus_images/14d79e1e8cdeb332dbbc0361773a2fdd44c8e038139299170f8d6a7e72326d65.png)

对应合约代码关系如下:

![配对合约继承ERC20合约](https://storage.googleapis.com/papyrus_images/a0ae8be47b83fc3bc983dfaa6bcf6d9f9a4487fea2247474508c9c536b013ef4.png)

配对合约继承ERC20合约

![工厂合约引用配对合约](https://storage.googleapis.com/papyrus_images/b07b927568831bdae4db5a0ce0395e37cae1c8fd9a44d6c7e0d6b7c158c2de6c.png)

工厂合约引用配对合约

### 工厂合约：

工厂合约是UniswapV2中的核心代码，所有的Pair合约都是通过工厂合约来进行部署的。工厂合约部分主要是两个功能，**一个是创建配对方法，另一个是收税地址和设置收税地址权限地址。**

创建配对方法 createPair()

![](https://storage.googleapis.com/papyrus_images/eaaa72efa4cc1e227af16acfd34565401a60628807ce793b11d270867b6c17c5.png)

该方法功能是创建一组新的交易对，传入的参数是；两个token的address,该方法比较关键的是create2，它是采用了内联汇编。那么为什么要采用create2方法来新建合约实例呢，主要是可以在**部署合约之前可以预先计算出合约的部署地址,从而使这个合约地址可预测，这样便于Router合约不进行任何调用，就可以计算得到Pair合约的地址。**

     bytes memory bytecode = type(UniswapV2Pair).creationCode;
            //将token0和token1打包后创建哈希
            bytes32 salt = keccak256(abi.encodePacked(token0, token1));
            // 内联汇编
            // solium-disable-next-line
            assembly {
                //通过create2方法布署合约,并且加盐,返回地址到pair变量
                pair := create2(0, add(bytecode, 32), mload(bytecode), salt)
            }
    

上面这三行代码就是提前计算pair合约地址，第一行是根据UniswapV2Pair合约代码的创建字节码createCode.第二行是根据两个代币地址计算出一个盐值。紧接着用 **assembly** 关键字包起一段内联汇编代码，通过调用create2操作码来创建新合约。

**收税地址和设置收税地址权限地址**

*   设置平台手续费收取地址
    
    权限控制人合约可以设定平台手续费是否收取以及收取地址。
    

![](https://storage.googleapis.com/papyrus_images/6a0e292ae9db50cf1aa57728d7be7d39b135c8270b90142442086749448556ef.png)

*   平台手续费收取权限控制
    
    原权限控制人，可以另外指派一个新的address来作为新的权限控制人。
    

![](https://storage.googleapis.com/papyrus_images/6fce503ac0789b0a50e3df728195a35b06290c168a6d31cfe3fb84899316abdb.png)

以上就是工厂合约的全部功能了，**在实际部署合约的时候，只需要部署工厂合约就可以了。因为配对合约是被引用的**，因此不需要再部署配对合约。

下篇分析配对合约，敬请期待！

---

*Originally published on [cyptoJune](https://paragraph.com/@cyptojune/defi-uniswap-v2)*
