Truffle +Hardhat 双框架实战指南

Truffle + Hardhat 双框架实战指南

1. 双框架集成概述

在现代以太坊开发中,Truffle 和 Hardhat 都是主流开发框架,各有优势:

  • Truffle:成熟生态,内置合约编译、测试、部署功能
  • Hardhat:强大灵活性,支持 TypeScript,插件系统丰富
项目初始化
Truffle 功能
Hardhat 功能
Ganache 集成
Mocha 测试
Hardhat Network
TypeScript 支持
本地开发链
传统测试
高级类型检查
智能合约

2. 环境配置与初始化

2.1 项目初始化

mkdir dual-framework-demo
cd dual-framework-demo
npm init -y

# 安装 Truffle
npm install -g truffle
truffle init

# 安装 Hardhat
npm install --save-dev hardhat
npx hardhat init

2.2 目录结构调整

dual-framework-demo/
├── contracts/               # 共享合约目录
├── migrations/              # Truffle 迁移脚本
├── scripts/                 # Hardhat 部署脚本
├── test/                    # 共享测试目录
│   ├── truffle/             # Truffle 测试
│   └── hardhat/             # Hardhat 测试
├── hardhat.config.js        # Hardhat 配置
└── truffle-config.js        # Truffle 配置

2.3 安装依赖

npm install --save-dev \
  @nomicfoundation/hardhat-toolbox \
  @truffle/hdwallet-provider \
  dotenv \
  chai \
  @types/chai \
  ts-node \
  typescript

3. 配置双框架环境

3.1 Hardhat 配置 (hardhat.config.js)

require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config();

module.exports = {
  solidity: "0.8.19",
  networks: {
    hardhat: {
      chainId: 1337,
    },
    goerli: {
      url: process.env.GOERLI_RPC_URL,
      accounts: [process.env.PRIVATE_KEY],
    }
  },
  paths: {
    sources: "./contracts",
    tests: "./test/hardhat",
    cache: "./cache_hardhat",
    artifacts: "./artifacts_hardhat"
  }
};

3.2 Truffle 配置 (truffle-config.js)

require("dotenv").config();
const HDWalletProvider = require("@truffle/hdwallet-provider");

module.exports = {
  contracts_build_directory: "./build_truffle",
  networks: {
    development: {
      host: "127.0.0.1",
      port: 8545,
      network_id: "*",
    },
    goerli: {
      provider: () => new HDWalletProvider({
        privateKeys: [process.env.PRIVATE_KEY],
        providerOrUrl: process.env.GOERLI_RPC_URL
      }),
      network_id: 5,
    }
  },
  compilers: {
    solc: {
      version: "0.8.19",
      settings: {
        optimizer: {
          enabled: true,
          runs: 200
        }
      }
    }
  }
};

4. 智能合约开发

4.1 创建示例合约 (contracts/SimpleStorage.sol)

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

contract SimpleStorage {
    uint256 private storedValue;
    
    event ValueChanged(uint256 newValue);
    
    function setValue(uint256 _value) public {
        storedValue = _value;
        emit ValueChanged(_value);
    }
    
    function getValue() public view returns (uint256) {
        return storedValue;
    }
}

5. 迁移与部署脚本

5.1 Truffle 迁移脚本 (migrations/1_deploy_contracts.js)

const SimpleStorage = artifacts.require("SimpleStorage");

module.exports = function (deployer) {
  deployer.deploy(SimpleStorage);
};

5.2 Hardhat 部署脚本 (scripts/deploy.ts)

import { ethers } from "hardhat";

async function main() {
  const SimpleStorage = await ethers.getContractFactory("SimpleStorage");
  const simpleStorage = await SimpleStorage.deploy();
  
  await simpleStorage.deployed();
  
  console.log(`SimpleStorage deployed to: ${simpleStorage.address}`);
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

6. 双框架测试集成

6.1 Truffle 测试 (test/truffle/simpleStorage.test.js)

const SimpleStorage = artifacts.require("SimpleStorage");

contract("SimpleStorage (Truffle)", (accounts) => {
  let simpleStorage;
  
  before(async () => {
    simpleStorage = await SimpleStorage.deployed();
  });
  
  it("should store a value", async () => {
    const newValue = 42;
    await simpleStorage.setValue(newValue);
    const storedValue = await simpleStorage.getValue();
    assert.equal(storedValue, newValue, "Value not stored correctly");
  });
  
  it("should emit ValueChanged event", async () => {
    const newValue = 100;
    const tx = await simpleStorage.setValue(newValue);
    assert.equal(tx.logs[0].event, "ValueChanged", "Event not emitted");
    assert.equal(tx.logs[0].args.newValue, newValue, "Event value incorrect");
  });
});

6.2 Hardhat 测试 (test/hardhat/simpleStorage.test.ts)

import { expect } from "chai";
import { ethers } from "hardhat";
import { SimpleStorage } from "../typechain-types";

describe("SimpleStorage (Hardhat)", function () {
  let simpleStorage: SimpleStorage;
  
  before(async () => {
    const SimpleStorageFactory = await ethers.getContractFactory("SimpleStorage");
    simpleStorage = await SimpleStorageFactory.deploy();
    await simpleStorage.deployed();
  });
  
  it("Should store a value", async () => {
    const newValue = 42;
    await simpleStorage.setValue(newValue);
    expect(await simpleStorage.getValue()).to.equal(newValue);
  });
  
  it("Should emit ValueChanged event", async () => {
    const newValue = 100;
    await expect(simpleStorage.setValue(newValue))
      .to.emit(simpleStorage, "ValueChanged")
      .withArgs(newValue);
  });
});

7. 双框架编译与测试

7.1 使用 Truffle

# 编译合约
truffle compile

# 启动开发链
truffle develop

# 在Truffle控制台内执行
migrate
test ./test/truffle/simpleStorage.test.js

7.2 使用 Hardhat

# 编译合约
npx hardhat compile

# 运行测试
npx hardhat test

8. 高级功能集成

8.1 TypeScript 支持配置 (tsconfig.json)

{
  "compilerOptions": {
    "target": "es2020",
    "module": "commonjs",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,
    "resolveJsonModule": true,
    "outDir": "dist",
    "rootDir": ".",
    "types": ["hardhat", "chai"]
  },
  "include": ["./scripts", "./test"]
}

8.2 集成 Hardhat 插件

npm install --save-dev \
  @nomiclabs/hardhat-etherscan \
  hardhat-gas-reporter \
  solidity-coverage

更新 hardhat.config.js:

require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config();
require("hardhat-gas-reporter");
require("solidity-coverage");

module.exports = {
  solidity: "0.8.19",
  networks: {
    // ...网络配置
  },
  etherscan: {
    apiKey: process.env.ETHERSCAN_API_KEY,
  },
  gasReporter: {
    enabled: process.env.REPORT_GAS ? true : false,
    currency: "USD",
    coinmarketcap: process.env.COINMARKETCAP_API_KEY,
  },
  paths: {
    // ...路径配置
  }
};

9. 双框架部署策略

9.1 Truffle 部署到 Goerli 测试网

truffle migrate --network goerli

9.2 Hardhat 部署到 Goerli 测试网

npx hardhat run scripts/deploy.ts --network goerli

9.3 验证合约 (Hardhat)

// scripts/verify.ts
import { run } from "hardhat";

async function verify() {
  const address = "0x..."; // 部署后的合约地址
  await run("verify:verify", {
    address: address,
    constructorArguments: [],
  });
}

verify().catch(console.error);

运行验证:

npx hardhat run scripts/verify.ts --network goerli

10. 实战工作流程示例

10.1 完整开发流程

开发者 Truffle Hardhat 合约 启动开发链 (truffle develop) 编译合约 (truffle compile) 运行基础测试 (truffle test) 编写高级测试 (Hardhat + TypeScript) 运行高级测试 (npx hardhat test) 代码覆盖率测试 (npx hardhat coverage) Gas 消耗分析 (npx hardhat gas-report) 部署到本地链 (truffle migrate) 部署到测试网 (npx hardhat run --network goerli) 验证合约 (npx hardhat verify) 开发者 Truffle Hardhat 合约

10.2 自动化脚本 (package.json)

{
  "scripts": {
    "truffle:compile": "truffle compile",
    "truffle:test": "truffle test ./test/truffle",
    "truffle:migrate": "truffle migrate",
    "truffle:migrate-goerli": "truffle migrate --network goerli",
    
    "hardhat:compile": "hardhat compile",
    "hardhat:test": "hardhat test ./test/hardhat",
    "hardhat:coverage": "hardhat coverage",
    "hardhat:gas": "REPORT_GAS=true hardhat test",
    "hardhat:deploy": "hardhat run scripts/deploy.ts",
    "hardhat:deploy-goerli": "hardhat run scripts/deploy.ts --network goerli",
    "hardhat:verify": "hardhat run scripts/verify.ts --network goerli",
    
    "dev": "npm run truffle:compile && npm run truffle:migrate && npm run truffle:test",
    "test": "npm run truffle:test && npm run hardhat:test",
    "deploy": "npm run hardhat:deploy-goerli && npm run hardhat:verify"
  }
}

11. 双框架优势整合

11.1 Truffle 核心优势

  • 成熟迁移系统:结构化部署流程
  • 内置开发控制台:交互式调试
  • Ganache 集成:可视化区块链管理
  • 广泛文档支持:初学者友好

11.2 Hardhat 核心优势

  • TypeScript 支持:强类型开发体验
  • 插件生态系统:丰富扩展功能
  • 高级调试功能console.log 在 Solidity
  • 任务系统:自定义工作流

11.3 最佳整合策略

开发阶段推荐框架原因
本地开发环境Truffle快速启动,内置控制台
合约编译双框架确保兼容性
基础测试Truffle简单快速
复杂测试HardhatTypeScript支持,高级断言
本地部署Truffle迁移脚本简单
测试网部署Hardhat更好的错误处理,插件支持
合约验证Hardhat集成化验证流程
性能分析HardhatGas报告,代码覆盖率

12. 常见问题解决方案

12.1 编译冲突问题

当两个框架同时编译时,解决方案:

# truffle-config.js
module.exports = {
+  contracts_build_directory: "./build_truffle",
  // ...
}

# hardhat.config.js
module.exports = {
  paths: {
+    artifacts: "./artifacts_hardhat"
  }
}

12.2 TypeScript 类型生成

安装类型生成工具:

npm install --save-dev typechain @typechain/hardhat @typechain/truffle-v5

配置 Hardhat:

// hardhat.config.js
require("@typechain/hardhat");
require("@nomiclabs/hardhat-ethers");

module.exports = {
  // ...
  typechain: {
    outDir: "typechain",
    target: "ethers-v5",
  },
};

配置 Truffle:

// truffle-config.js
require("@typechain/truffle-v5");

module.exports = {
  // ...
  plugins: ["@typechain/truffle-v5"],
  typechain: {
    outDir: "typechain-truffle",
  },
};

12.3 共享合约目录技巧

hardhat.config.jstruffle-config.js 中设置相同的合约目录:

// 两个配置文件中
{
  // ...
  paths: {
    sources: "./contracts"
  }
}

13. 生产环境最佳实践

13.1 安全加固措施

  • 合约验证:部署后立即验证源码
  • 多签名部署:关键操作使用 Gnosis Safe
  • 自动化测试:CI/CD 集成测试流程
  • 依赖锁定:使用 package-lock.jsonyarn.lock

13.2 性能优化

// 在两个框架的配置中启用优化器
compilers: {
  solc: {
    version: "0.8.19",
    settings: {
      optimizer: {
        enabled: true,
        runs: 200  // 优化程度,值越大Gas越少但字节码越大
      }
    }
  }
}

13.3 持续集成配置 (GitHub Actions)

name: CI Pipeline

on: [push]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: 18
    - name: Install dependencies
      run: npm ci
    - name: Run Truffle tests
      run: npm run truffle:test
    - name: Run Hardhat tests
      run: npm run hardhat:test
    - name: Run Hardhat coverage
      run: npm run hardhat:coverage
    - name: Run Hardhat gas report
      run: npm run hardhat:gas
      
  deploy:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
    - uses: actions/checkout@v3
    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: 18
    - name: Install dependencies
      run: npm ci
    - name: Deploy to Goerli
      run: npm run deploy
      env:
        PRIVATE_KEY: ${{ secrets.DEPLOYER_PRIVATE_KEY }}
        GOERLI_RPC_URL: ${{ secrets.GOERLI_RPC_URL }}
        ETHERSCAN_API_KEY: ${{ secrets.ETHERSCAN_API_KEY }}

结论:双框架工作流优势

通过整合 Truffle 和 Hardhat,开发者可以创建强大的混合开发环境:

  1. 本地开发:使用 Truffle + Ganache 快速原型开发
  2. 测试阶段
    • Truffle 用于基础功能测试
    • Hardhat 用于复杂场景和 TypeScript 测试
  3. 部署流程
    • Truffle 用于简单本地部署
    • Hardhat 用于生产环境部署和验证
  4. 维护阶段
    • Hardhat 插件用于监控和优化
    • 双框架确保兼容性和灵活性

关键建议

  1. 统一合约目录,分离编译输出
  2. 使用 TypeScript 增强代码质量
  3. 自动化测试和部署流程
  4. 定期同步两个框架的 Solidity 版本
  5. 利用 Hardhat 插件扩展功能

Truffle 和 Hardhat 双框架策略为以太坊开发者提供了从初学者到高级项目的完整工具链,平衡了易用性和灵活性,是现代 DApp 开发的最佳实践。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

闲人编程

你的鼓励就是我最大的动力,谢谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值