Mik*_*maa 5 ethereum ganache hardhat brownie uniswap
我正在编写一个自动化测试套件,需要针对 Uniswap v2 风格的自动做市商测试功能:进行掉期并使用不同的订单路由。因此,需要部署路由器。
是否有任何现有示例说明如何在 Brownie 中部署可测试的 Uniswap v2 风格交换?因为 Brownie 是智能合约开发者中的少数,那么 Truffle 或 Hardhat 有没有例子呢?
我也在探索使用主网分叉的选项,但我不确定此操作是否太昂贵(慢)而无法用于单元测试。
使用本地测试网可以让您在测试期间非常精确地控制区块链的状态。但是,它将要求您手动部署所需的每个合约。
主网的分叉将使您不必部署主网上已部署的每个合约。然而,您将牺牲对环境的控制,并且需要连接到节点。
我已经在测试网上部署了 Uniswap 2V 几次。为此,您需要以下合约的字节码和 ABI:UniswapV2Factory、UniswapV2Pair、UniswapV2Router02(我想您需要第二个版本的路由器)。Uniswap 文档很好地解释了如何从 NPM 下载它们。为了使路由器正常工作,您还需要部署 WETH 合约。我建议从这个 github页面部署一个。
在运行此代码之前,只需确保您的链正在运行。对于安全帽,运行以下命令:
npx hardhat node
Run Code Online (Sandbox Code Playgroud)
首先将您的签名者连接到您的开发链:
var provider = new ethers.providers.WebSocketProvider("ws://localhost:8545");
var signer = provider.getSigner();
Run Code Online (Sandbox Code Playgroud)
使用 ethers.js 库,首先部署工厂:
const compiledUniswapFactory = require("@uniswap/v2-core/build/UniswapV2Factory.json");
var uniswapFactory = await new ethers.ContractFactory(compiledUniswapFactory.interface,compiledUniswapFactory.bytecode,signer).deploy(await signer.getAddress());
Run Code Online (Sandbox Code Playgroud)
那么WETH合约:
const compiledWETH = require("canonical-weth/build/conrtacts/WETH.json";
var WETH = await new ethers.ContractFactory(WETH.interface,WETH.bytecode,signer).deploy();
Run Code Online (Sandbox Code Playgroud)
您现在可以部署路由器。
const compiledUniswapRouter = require("@uniswap/v2-periphery/build/UniswapV2Router02");
var router = await new ethers.ContractFactory(compiledUniswapRouter.abi,compiledUniswapRouter.bytecode,signer).deploy(uniswapFactory.address,WETH.address);
Run Code Online (Sandbox Code Playgroud)
您还需要部署所需的 ERC20 代币(这是我编写的代币示例):
const compiledERC20 = require("../../../Ethereum/Ethereum/sources/ERC20.sol/Token.json");
var erc20Factory = new ethers.ContractFactory(compiledERC20.abi,compiledERC20.bytecode,signer);
var erc20_0 = await erc20Factory.deploy("1000000", "Token 0", "5", "T0");
var erc20_1 = await erc20Factory.deploy("1000000", "Token 1", "5", "T1");
Run Code Online (Sandbox Code Playgroud)
部署函数的参数将取决于您要部署的令牌的构造函数。
您还需要使用 Uniswap 工厂的 createPair 方法创建对。
uniswapFactory.createPair(erc20_0.address,erc20_1.address);
Run Code Online (Sandbox Code Playgroud)
请记住,在该对中,代币将由合约任意排序。ERC20_0 可能不是两者中的第一个。
之后,只需等待所有事务完成,您就可以开始测试了。
为了快速简单的设置,我会使用 Hardhat 的主网分支。
就像 @Xavier 所说,使用主网分叉意味着您不必部署您想要交互的每个合约。如果您想针对多个交易所测试您的合约,这将是最简单的方法。然而,它确实需要连接到节点,因此您的单元测试会运行得更慢。
举个例子,假设我想测试以下合约,该合约使用该swapExactETHForTokens方法在 Uniswap 上将 ETH 交换为 ERC20 代币。
pragma solidity ^0.6.6;
interface IUniswap {
function swapExactETHForTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline)
external
payable
returns (uint[] memory amounts);
function WETH() external pure returns (address);
}
contract UniswapTradeExample {
IUniswap uniswap;
// Pass in address of UniswapV2Router02
constructor(address _uniswap) public {
uniswap = IUniswap(_uniswap);
}
function swapExactETHForTokens(uint amountOutMin, address token) external payable {
address[] memory path = new address[](2);
path[0] = uniswap.WETH();
path[1] = token;
uniswap.swapExactETHForTokens{value: msg.value}(
amountOutMin,
path,
msg.sender,
now
);
}
}
Run Code Online (Sandbox Code Playgroud)
从 Hardhat 文档来看,要做的第一件事是使用Alchemy建立与存档节点的连接,该节点可以免费使用。
获得节点的 URL 后,将其作为网络添加到 Hardhat.config.js 文件中:
pragma solidity ^0.6.6;
interface IUniswap {
function swapExactETHForTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline)
external
payable
returns (uint[] memory amounts);
function WETH() external pure returns (address);
}
contract UniswapTradeExample {
IUniswap uniswap;
// Pass in address of UniswapV2Router02
constructor(address _uniswap) public {
uniswap = IUniswap(_uniswap);
}
function swapExactETHForTokens(uint amountOutMin, address token) external payable {
address[] memory path = new address[](2);
path[0] = uniswap.WETH();
path[1] = token;
uniswap.swapExactETHForTokens{value: msg.value}(
amountOutMin,
path,
msg.sender,
now
);
}
}
Run Code Online (Sandbox Code Playgroud)
如果你设置了blockNumber,Harhat 每次都会分叉这个区块。如果您正在使用测试套件并希望测试具有确定性,则建议您这样做。
最后,这是测试类,用于测试swapExactETHForTokens上述合约中的内容。举个例子,我用 1 ETH 交换 DAI。
networks: {
hardhat: {
forking: {
url: "https://eth-mainnet.alchemyapi.io/v2/<key>",
blockNumber: 14189520
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意const ERC20ABI = require('./ERC20.json');顶部的 ,它导入了获取 DAI 合约并使用其方法所需的ERC20ABIbalanceOf()。
就这样。运行npx hardhat test应该表明该测试通过。
| 归档时间: |
|
| 查看次数: |
2714 次 |
| 最近记录: |