手把手教你从0到1构建Uniswap V1:part3

  • Louis
  • 发布于 2024-07-21 18:54
  • 阅读 1420

在前面的两篇文章中,我们已经已经实现了Exchange合约的所有核心机制,包括定价功能、交换、LP代币和费用。看起来已经比较完善了,但是还缺少了一部分:工厂合约。本篇文章,我们就来实现它。

开篇介绍

在前面的两篇文章中,我们已经已经实现了Exchange合约的所有核心机制,包括定价功能、交换、LP代币和费用。看起来已经比较完善了,但是还缺少了一部分:工厂合约。本篇文章,我们就来实现它。

工厂合约的作用是什么

事实上工厂合约充当的角色是Exchange合约的注册表:每个新部署的Exchange合约都在工厂中注册。这是一个重要的机制:任何Exchange合约都可以通过查询注册表找到。通过注册表,当用户尝试将一个Token代币交换为另一个Token代币(而不是以太币)的时候,Exchange合约可以通过工厂合约找到其他的Exchange合约。

工厂合约提供的另一个比较实用的功能是能够方便的部署Exchange合约而无需处理代码、节点、部署脚本和任何其他开发工具。

Factory实现了一个功能,允许用户只需调用该函数即可创建和部署Exchange合约。所以,今天我们还将学习一个合约如何部署另一个合约。

Uniswap 只有一份工厂合约,因此只有一份 Uniswap 交易对的注册表。然而,没有什么可以阻止其他用户部署自己的工厂,甚至是未在官方工厂注册的Exchange合约。虽然这是可能的,但这样的交易所不会被 Uniswap 认可,也无法通过官方网站使用它们来交换代币。

让我们看看代码如何实现:

工厂合约的实现

工厂合约本质上是一个注册表,我们需要一个数据结构来存储Exchange合约,这应该是一个地址到地址的映射,它允许通过代币查找另外一个代币(1 个交换只能交换 1 个代币,还记得吗?)。

pragma solidity ^0.8.24;

import "./Exchange.sol";

contract Factory {
    mapping(address => address) public tokenToExchange;

    ...

接下来是 createExchange 函数,它允许通过Token地址来创建和部署Exchange合约:

function createExchange(address _tokenAddress) public returns (address) {
  require(_tokenAddress != address(0), "invalid token address");
  require(
    tokenToExchange[_tokenAddress] == address(0),
    "exchange already exists"
  );

  Exchange exchange = new Exchange(_tokenAddress);
  tokenToExchange[_tokenAddress] = address(exchange);

  return address(exchange);
}

让我们来做个简单的梳理:

这里有两项检查:

1、第一个确保令牌地址不是零地址( 0x0000000000000000000000000000000000000000 )。

2、下一步确保Token合约还没有被添加到注册表中(默认地址值为零地址)。我们的想法是,我们不希望同一个Token代币有不同的Exchange合约,因为我们不希望流动性分散在多个Exchange合约中。它应该更好地集中在一个Exchange合约,以减少滑点并提供更好的汇率。

Exchange exchange = new Exchange(_tokenAddress);

创建一个新的 Exchange 合约实例,并将 _tokenAddress 传递给该合约的构造函数。

我们使用提供的代币地址实例化 Exchange,这就是我们之前需要导入“Exchange.sol”的原因。这种实例化类似于OOP语言中的类实例化,但是,在Solidity中, new 操作符实际上会部署一个合约。返回的值具有Exchange合约的类型,并且每个合约都可以转换为地址 - 这就是我们在下一行中所做的,以获取新交易所的地址并将其保存到注册表中。

tokenToExchange[_tokenAddress] = address(exchange);
return address(exchange);

将新创建的 Exchange 合约地址存储在映射 tokenToExchange 中,以便以后可以通过代币地址查找到对应的兑换合约。返回新创建的 Exchange 合约的地址。

要完成合约,我们只需要再实现一个函数 - getExchange ,这将允许我们通过另一个合约的接口查询注册表:


function getExchange(address _tokenAddress) public view returns (address) {
  return tokenT...

剩余50%的内容订阅专栏后可查看

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Louis
Louis
web3 developer,技术交流或者有工作机会可加VX: magicalLouis