# uniswap工厂合约代码详解

By [Cognitive](https://paragraph.com/@cognitive) · 2022-11-19

---

准备练习一下uniswap的合约，今天先开始第一讲，uniswap的工厂合约的代码详解。

推荐视频：

[![]({{DOMAIN}}/editor/youtube/play.png)](https://www.youtube.com/watch?v=38mVbslZpS4)

工厂合约代码：

\`// SPDX-License-Identifier: MIT pragma solidity =0.8.17;

import './interfaces/IUniswapV2Factory.sol'; import './UniswapV2Pair.sol';

contract UniswapV2Factory is IUniswapV2Factory { address public feeTo; //收税地址 address public feeToSetter; //收税权限控制地址 //配对映射，地址->(地址->地址) mapping(address => mapping(address => address)) public getPair; //所有配对的数组 address\[\] public allPairs; //event 配对被创建 event PairCreated(address indexed token0, address indexed token1, address pair, uint256);

    //构造函数-定义收税权限地址
    constructor(address _feeToSetter) public {
        feeToSetter = _feeToSetter;
    }
    
    //查询配对数组长度
    function allPairsLength() external view returns (uint256) {
        return allPairs.length;
    }
    
    //创建配对合约，返回配对地址pair
    function createPair(address tokenA, address tokenB) external returns (address pair) {
        //确定tokenA不等于tokenB
        require(tokenA != tokenB, 'UniswapV2: IDENTICAL_ADDRESSES');
        //三目运算，如果A<B那么A在前B再后，否则相反，然后赋值为0和1
        (address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
        //确定0不等于0地址，那么1也自然不需要判断
        require(token0 != address(0), 'UniswapV2: ZERO_ADDRESS');
        //确定配对映射中不存在0和1的交易对。
        require(getPair[token0][token1] == address(0), 'UniswapV2: PAIR_EXISTS'); // single check is sufficient
        //type(合约名).creationCode可以获得合约编译后的bytecode
        bytes memory bytecode = type(UniswapV2Pair).creationCode;
        //将0和1打包好通过keccak256创建哈希
        bytes32 salt = keccak256(abi.encodePacked(token0, token1));
        //内联汇编
        //通过create2方法部署合约，返回地址给pair变量
        //mload(获取bytecode的长度)
        assembly {
            pair := create2(0, add(bytecode, 32), mload(bytecode), salt)
        }
        //对pair合约进行初始化操作
        IUniswapV2Pair(pair).initialize(token0, token1);
        //配对映射设置0>=1=pair
        getPair[token0][token1] = pair;
        //配对映射设置1>=0=pair
        getPair[token1][token0] = pair; // populate mapping in the reverse direction
        //pair地址加入allPairs数组中
        allPairs.push(pair);
        //触发配对成功事件
        emit PairCreated(token0, token1, pair, allPairs.length);
    }
    
    //设置收税地址
    function setFeeTo(address _feeTo) external {
        require(msg.sender == feeToSetter, 'UniswapV2: FORBIDDEN');
        feeTo = _feeTo;
    }
    
    //设置收税权限控制地址
    function setFeeToSetter(address _feeToSetter) external {
        require(msg.sender == feeToSetter, 'UniswapV2: FORBIDDEN');
        feeToSetter = _feeToSetter;
    }`

---

*Originally published on [Cognitive](https://paragraph.com/@cognitive/uniswap)*
