首页 > 其他分享 >学习Foundry的理由

学习Foundry的理由

时间:2024-09-24 17:13:34浏览次数:8  
标签:理由 代币 Foundry 学习 地址 余额 mint ERC20

来自于跟ChatGPT老师的讨论。
学习 Foundry 对于你进行 DeFi 开发来说是一个不错的选择。Foundry 有以下几个优势:

  1. 速度和效率:Foundry 在编译和运行测试时比 Hardhat 更快。它使用基于 Rust 的工具来提高速度,这在处理大型项目和频繁测试时非常有用。

  2. 内置模糊测试:Foundry 自带模糊测试功能,能够通过提供随机输入有效地测试极端情况。这在 DeFi 系统中尤其重要,因为可以更好地检测潜在的边缘案例。

  3. 主网分叉:和 Hardhat 一样,Foundry 也支持主网分叉测试,但通常速度更快。这样你可以更容易地模拟真实世界中的 DeFi 交互,例如测试现有流动性池或在分叉主网上进行代币转账。

  4. 自定义 Solidity 脚本:Foundry 允许你使用 Solidity 编写脚本,使得直接与合约进行交互更加方便,因为你使用的语言和开发时是一样的。

鉴于你当前的背景以及对 DeFi Dex 合约的专注,Foundry 的工具和功能将帮助你优化测试、模拟和通过实践进行学习。

我看在Foundry里可以用deal(address(USDT), address(this), 1e6 * 1e6)这样的方式给指定的地址设置某个代币的余额,如果用Hardhat能做到吗?

在 Hardhat 中,没有像 Foundry 那样的原生 deal 方法直接修改代币余额,但你可以通过模拟代币合约的方式来实现类似的功能。通常的方法是通过与代币合约的 minttransfer 函数交互来为某个地址设置余额。

如果你想在 Hardhat 中模拟像 deal 这样的方法,可以通过以下几种方式实现:

1. 使用 Forked Mainnet(主网分叉)

在 Hardhat 中,你可以使用主网分叉模式来测试真实代币的交互。你可以将真实的 ERC20 代币转账到某个地址。

// 使用 USDT 代币合约的 ABI 和地址
const USDT_ABI = [ /* USDT ABI */ ];
const USDT_ADDRESS = "0x..."; // USDT 合约地址
const usdt = new ethers.Contract(USDT_ADDRESS, USDT_ABI, signer);

// 给某个地址转账 USDT
await usdt.transfer(recipientAddress, ethers.utils.parseUnits("1000", 6)); // 转账 1000 USDT

2. 使用 Mock Token(模拟代币合约)

如果你只是在测试环境中,可以部署一个模拟的 ERC20 代币合约,然后在需要时调用 mint 函数直接给某个地址设置余额。

// ERC20 Mock Token 合约
contract MockERC20 is ERC20 {
    constructor() ERC20("Mock Token", "MKT") {}

    function mint(address to, uint256 amount) external {
        _mint(to, amount);
    }
}

在你的测试中调用 mint 方法:

const mockToken = await MockERC20.deploy();
await mockToken.mint(address, ethers.utils.parseUnits("1000", 18)); // 设置余额

3. Hardhat Impersonation(账户模拟)

如果你是在主网分叉上操作现有的代币合约,可以使用 Hardhat 的 impersonateAccount 方法来模拟任何账户(例如,使用代币合约的管理员地址来 mint 或转账代币)。

await hre.network.provider.request({
  method: "hardhat_impersonateAccount",
  params: ["0x..."], // 代币合约的管理员地址
});

const signer = await ethers.getSigner("0x...");
await token.connect(signer).mint(recipient, amount);

总结

虽然 Hardhat 本身没有像 Foundry 中的 deal 函数直接设置代币余额的功能,但你可以通过以上几种方法,在测试中实现类似的功能。

方法3需要我去查询实际主网上一些有足够余额的地址来进行冒充。方法1也是一样,signer地址需要在主网上有相应的代币余额。我不想去找这些账户地址,而hardhat内置生成的模拟账户似乎每个地址只有100ETH,没有其他代币。我想有个能给模拟账户增加指定代币指定余额的方法,这个能实现吗?

在 Hardhat 中,确实没有像 Foundry 那样的原生方法可以直接给账户增加指定代币的余额。然而,有一个变通方法可以模拟这种效果——通过部署一个 ERC20 代币合约(或 Mock 代币),并在需要时手动调用 mint 函数为指定的模拟账户增加余额。这个方法不需要使用主网地址或实际存在的代币余额,也不需要 impersonate 账户。

以下是如何实现的详细步骤:

1. 部署 Mock Token(模拟代币合约)

你可以部署一个自定义的 ERC20 代币合约,并在测试过程中调用 mint 函数向模拟账户增加余额。

Step 1: 创建一个 Mock ERC20 代币合约

首先,定义一个简单的 ERC20 合约,它包含一个 mint 函数:

// contracts/MockERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MockERC20 is ERC20 {
    constructor(string memory name, string memory symbol) ERC20(name, symbol) {}

    function mint(address to, uint256 amount) external {
        _mint(to, amount);
    }
}

Step 2: 在测试脚本中部署 Mock Token 合约

在你的 Hardhat 测试脚本中,部署这个合约并调用 mint 方法给指定的账户增加余额。

const { ethers } = require("hardhat");

async function main() {
  // 部署 MockERC20 合约
  const MockERC20 = await ethers.getContractFactory("MockERC20");
  const mockToken = await MockERC20.deploy("Mock Token", "MKT");
  await mockToken.deployed();

  console.log(`Mock Token 部署在: ${mockToken.address}`);

  // 获取模拟账户
  const [owner, addr1] = await ethers.getSigners();

  // 给 addr1 增加 1000 个代币
  const mintAmount = ethers.utils.parseUnits("1000", 18); // 假设 18 位小数
  await mockToken.mint(addr1.address, mintAmount);

  // 验证余额
  const balance = await mockToken.balanceOf(addr1.address);
  console.log(`Addr1 的代币余额为: ${ethers.utils.formatUnits(balance, 18)}`);
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error);
    process.exit(1);
  });

2. 测试现有 ERC20 代币

如果你需要使用主网上存在的真实代币,并希望在本地测试环境下直接控制余额,可以选择主网分叉模式并使用 mint 函数,但如果无法直接控制代币的 mint 权限,则这种方式不适用。

总结

通过在测试环境中使用 Mock 代币合约,你可以模拟任何 ERC20 代币的行为,并为指定的模拟账户自由设置余额。这样就避免了去找真实地址或实际代币余额的问题,适用于大多数本地测试场景。如果你确实需要在测试环境中模拟真实的代币,则需要通过分叉主网并找到可以转账的地址来进行测试。

我的需求类似上面的2,是要使用主网上存在的代币,然而hardhat生成的模拟地址大概率是没有mint权限的,这就需要找到真实的有实际余额的地址。看来这个方面还是Foundry更好用了。

确实,针对你希望在测试中使用主网上存在的真实代币并为模拟账户设置余额的需求,Foundry 提供的 deal 方法确实更加方便。它允许直接为指定地址设置代币余额,而无需关心代币是否有 mint 权限或去寻找主网上真实有余额的地址。这大大简化了测试过程,特别是当你需要测试多个不同代币时。

相比之下,Hardhat 在这方面需要更多手动步骤,比如通过分叉主网找到有足够余额的地址并进行 impersonate,或者自己部署和管理 mock 代币来模拟真实代币的行为。而这些在 Foundry 中都可以直接通过 deal 来轻松完成。

所以如果你的测试需求频繁涉及主网上存在的真实代币,特别是大规模测试不同的账户和代币余额的情况,Foundry 的确是一个更合适的选择。

标签:理由,代币,Foundry,学习,地址,余额,mint,ERC20
From: https://www.cnblogs.com/lyhero11/p/18429607

相关文章

  • 详解机器学习经典模型(原理及应用)——KNN
    一、什么是KNN        K最近邻(K-NearestNeighbors,KNN)是一种简单而强大的机器学习算法,它基于一个基本的假设:相似的样本通常在特征空间中彼此接近。KNN算法通过查找一个样本的最近K个邻居来预测该样本的类别或属性。二、KNN算法流程        KNN没有显式的训......
  • 机器学习模型中特征贡献度分析:预测贡献与错误贡献
    在机器学习领域,特征重要性分析是一种广泛应用的模型解释工具。但是特征重要性并不等同于特征质量。本文将探讨特征重要性与特征有效性之间的关系,并引入两个关键概念:预测贡献度和错误贡献度。核心概念预测贡献度:衡量特征在模型预测中的权重,反映模型在训练集上识别的模式。这与传统的......
  • 利用未标记数据的半监督学习在模型训练中的效果评估
    数据科学家在实践中经常面临的一个关键挑战是缺乏足够的标记数据来训练可靠且准确的模型。标记数据对于监督学习任务(如分类或回归)至关重要。但是在许多领域,获取标记数据往往成本高昂、耗时或不切实际。相比之下,未标记数据通常较易获取,但无法直接用于模型训练。如何利用未标记数据来......
  • rust学习_闭包
    闭包定义声明使用1.闭包是什么   1.闭包允许在其定义的作用域之外访问变量 2.闭包如何声明   leta= |传递给闭包的参数| ->闭包返回的类型{       闭包的实现   }3.如何调用闭包  像调用函数一样被调用letresult=函数名(参数1,参......
  • UnoCSS 给了我一个不用 tailwindcss 的理由
    如果你没有听说过 tailwindcss或者 unocss,请先 return 先去了解一下。开发上:可能为你甚至你们的前端团队节省很多写样式的时间,也能让你或者你们的项目开发体验有很大提升生产上:你们的项目打出来的包体积中的样式代码占比将突然骤降然后趋于不变。为什么我换到了UnoCSSt......
  • 阅读《AI大模型开发之路》的十大理由
    作为一名技术博主,我最近读完了《AI大模型开发之路》这本书,深感这是一部值得推荐的佳作。如果你对AI大模型感兴趣,或者希望在这个领域有所提升,那么这本书绝对不容错过。以下是我推荐你阅读《AI大模型开发之路》的十大理由:1.全面覆盖AI大模型开发的各个方面从基础理论到实践应......
  • Python学习: with open()、os.open()、open()的详细使用
    1.读写文件背景读写文件是最常见的IO操作。Python内置了读写文件的函数,用法和C是兼容的。在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘。读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操作系统提供的接口从这个文......
  • 一、机器学习算法与实践_04信息论与决策树算法笔记
    1信息论基础知识介绍信息论是运用概率论与数理统计的方法,去研究信息、信息熵、通信系统、数据传输、密码学、数据压缩等问题的应用数学学科,熵(Entropy)是信息论中的一个重要概念,由克劳德·香农(ClaudeShannon)提出,用于衡量信息的不确定性或系统的混乱程度在机器学习中,熵的概念......
  • 【智能流体力学 1/3理论课程2/3实操课程】深度学习技术在流体力学中的应用与实操培训
    智能流体力学及其仿真技术应用实战前沿背景在当今科学技术快速发展的背景下,流体力学和计算流体力学(CFD)正经历着深刻的变革。传统的流体仿真技术已无法满足日益复杂和高精度的工程需求,而深度学习和人工智能技术的飞速进步,为流体力学的研究和应用提供了新的解决方案。以下是......
  • 日新月异 PyTorch - pytorch 基础: 通过卷积神经网络(Convolutional Neural Networks,
    源码https://github.com/webabcd/PytorchDemo作者webabcd日新月异PyTorch-pytorch基础:通过卷积神经网络(ConvolutionalNeuralNetworks,CNN)做图片分类-通过ResNet50做图片分类的学习(对cifar10数据集做训练和测试),保存训练后的模型,加载训练后的模型并评估指定的......