Hardhat vs Foundry:选择合适的以太坊开发工具

以下是在 Hardhat 和 Foundry 之间做选择时需要考虑的一些因素。

5 分钟阅读
Hardhat vs Foundry:选择合适的以太坊开发工具

为您的 dapp 开发选择合适的工具,不仅会影响开发效率,还会对智能合约的测试、部署和维护效果产生重要影响。在本文中,我们将对以太坊 dapp 开发者常用的两款工具进行比较:Foundry 与 Hardhat,重点介绍它们的安装要求、测试与部署工作流程,以及各自的技术特点与局限性。

关于 Hardhat

Hardhat 是一个成熟的开发环境,旨在帮助开发者管理和自动化智能合约开发中涉及的各类任务,以其灵活性和适应性著称。Hardhat 内置了 Hardhat Network——一个专为开发设计的本地以太坊网络,支持便捷的测试、部署和调试操作。

开发者可以通过交互式控制台直接与部署在 Hardhat Network 上的智能合约进行交互,提供了一个专为开发任务量身定制的完整本地环境。Hardhat 还支持丰富的插件生态系统,让开发者能够轻松扩展其功能。不过,部分用户可能会觉得 Hardhat 的初始配置较为复杂。

关于 Foundry

相比之下,Foundry 是一款相对较新的开发工具包,注重速度与可靠性。它基于 Forge 构建——一个强大的测试框架,使开发者能够高效地编写、编译和测试智能合约。Foundry 的核心优势之一在于其快速测试能力,Forge 测试框架能够大幅缩短测试执行时间,让开发者迭代更加迅速。

此外,Foundry 内置了原生调试工具,帮助开发者在环境内直接诊断和修复问题。Foundry 还能与以太坊生态系统中的其他工具无缝集成,使开发流程更加顺畅。不过,由于相对较新,Foundry 在社区支持方面可能不及更成熟的工具丰富。

Hardhat 与 Foundry 技术对比

在本节中,我们将使用一个基础的随机求和智能合约。该智能合约在 Hardhat 和 Foundry 中保持一致,但两个框架的项目配置方式略有不同。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract RandomSum {
    // Function to generate a pseudo-random number based on input
    function random(uint seed) private view returns (uint) {
        return uint(keccak256(abi.encodePacked(block.timestamp, msg.sender, seed))) % 100;
    }

    // Function to generate two random numbers and return their sum
    function generateSum() public view returns (uint sum) {
        uint num1 = random(1);
        uint num2 = random(2);
        sum = num1 + num2;
    }
}
复制

安装:

Hardhat:

要开始使用 Hardhat,您需要在本机上安装 Node.js。完成后,按照以下步骤创建新的 Hardhat 项目:

  1. 初始化新的 Node.js 项目:

mkdir randomsum
cd randomsum
npm init -y
复制
  1. 安装 Hardhat:

npm install --save-dev hardhat
  1. 创建 Hardhat 项目:

npx hardhat
  1. 按照提示创建基础项目。选择"Create an empty hardhat.config.js"进行最简配置,或选择创建示例项目。这将建立一个包含所有必要配置的 Hardhat 环境。

合约:将您的 RandomSum 合约放置在 contracts 文件夹中。

Foundry

Foundry 使用 Rust,因此您需要在系统上安装 Rust。准备好 Rust 后,运行以下命令安装 Foundry:

  1. 安装 Foundry:

curl -L <https://foundry.paradigm.xyz> | bash
foundryup
复制
  1. 初始化新的 Foundry 项目:

forge init randomsum-foundry
cd randomsum-foundry
复制

合约:将您的 RandomSum 合约放置在 src 目录中。

本地区块链部署

Hardhat

  • 本地区块链:使用 Hardhat Network,在执行测试或部署合约等任务时会自动运行。

  • 部署脚本:在 scripts/deploy.js 下创建脚本:

async function main() {
    const RandomSum = await ethers.getContractFactory("RandomSum");
    const randomSum = await RandomSum.deploy();
    await randomSum.deployed();
    console.log("RandomSum deployed successfully:");
}

main().catch((error) => {
    console.error(error);
    process.exit(1);
});
复制
  • 运行部署:执行以下命令进行部署:

npx hardhat run scripts/deploy.js --network localhost

Foundry

  • 本地区块链:Foundry 使用 anvil,一个本地以太坊节点。在单独的终端中运行以下命令启动本地节点。

anvil
  • 部署脚本:直接使用 forge create 命令:

forge create RandomSum --private-key YOUR_PRIVATE_KEY --rpc-url

测试网部署

Hardhat

  • 网络配置:在 hardhat.config.js 中配置目标网络,添加相应的网络设置(例如 Sepolia)。

module.exports = {
  solidity: "0.8.0",
  networks: {
    sepolia: {
      url: "https://linea-sepolia.infura.io/v3/YOUR_INFURA_KEY",
      accounts: [`0x${process.env.PRIVATE_KEY}`]
    }
  }
};
复制
  • 部署:使用相同的部署脚本,将网络选项更改为 Sepolia 后运行。

Foundry

  • 网络配置:无需额外的配置文件,直接在命令中指定网络即可。

  • 部署:使用:

forge create RandomSum --private-key YOUR_PRIVATE_KEY --rpc-url

智能合约测试

Hardhat

  • 编写测试:使用 JavaScript 在 test/randomSum.js 中创建测试文件:

const { expect } = require("chai");

describe("RandomSum", function() {
  it("Should return the sum of two random numbers", async function() {
    const RandomSum = await ethers.getContractFactory("RandomSum");
    const randomSum = await RandomSum.deploy();
    await randomSum.deployed();

    const sum = await randomSum.generateSum();
    expect(sum).to.be.a('number');
  });
});
复制
  • 运行测试:执行以下命令:

npx hardhat test

如果测试遇到问题,只需从 @nomicfoundation/hardhat-toolbox/network-helpers 中添加 loadFixture 函数即可。

使用 loadFixture 的主要优势包括:

  • 通过回滚到快照,为每个测试建立干净的环境。

  • 比为每个测试重新部署合约更加高效。

  • 支持在多个测试之间共享配置代码。

Foundry

  • 编写测试:使用 Solidity 在 test/RandomSum.t.sol 中添加测试文件:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "ds-test/test.sol";
import "../src/RandomSum.sol";

contract RandomSumTest is DSTest {
  RandomSum randomSum;

  function setUp() public {
    randomSum = new RandomSum();
  }

  function testGenerateSum() public {
    uint sum = randomSum.generateSum();
    assertTrue(sum >= 0 && sum <= 198); // since each random number is <100
  }
}
复制
  • 运行测试:使用:

forge test

总结

在 Hardhat 和 Foundry 之间做出选择,往往取决于团队的技术背景和项目的具体需求。如果团队擅长 JavaScript 并需要与 Web 技术进行深度集成,Hardhat 可能是更好的选择。其丰富的插件生态系统和灵活的开发环境,使其非常适合需要高度定制化并与各类 Web 技术交互的项目。

另一方面,如果项目需要快速迭代且专注于智能合约本身,Foundry 提供了一个极具吸引力的高效选择,让一切都在 Solidity 生态系统内完成。其速度优势和对 Solidity 的原生支持,能够显著提升专注于智能合约开发的团队的生产力。

总体而言,两款工具各有所长,最终的选择取决于您项目的独特需求以及团队的专业能力。

AI 翻译。可能包含错误。请务必核实信息。

评价此翻译