1. 项目概述
在区块链开发领域,ERC-20代币标准已经成为创建可互换代币的黄金标准。而Polkadot Hub作为新一代多链架构平台,为开发者提供了更灵活的部署选择。本文将带你使用Hardhat这一专业级以太坊开发环境,在Polkadot Hub上完成ERC-20代币的完整部署流程。
为什么选择这个技术栈组合?Hardhat提供了完善的智能合约开发工具链,包括测试框架、本地网络和插件系统;而Polkadot Hub则通过其EVM兼容层,让以太坊开发者可以无缝迁移到其高性能网络上。这种组合既保留了以太坊生态的开发便利性,又能享受Polkadot网络的跨链优势。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与工具配置
2.1 开发环境搭建
首先确保你的系统已安装Node.js(建议v16+)和npm/yarn。我们将使用yarn作为包管理器:
bash复制mkdir polkadot-erc20 && cd polkadot-erc20
yarn init -y
yarn add --dev hardhat
初始化Hardhat项目:
bash复制npx hardhat
选择"Create a JavaScript project"(TypeScript也可选,但本文以JS为例),保持默认配置即可。这会生成基础项目结构,包括contracts、scripts和test目录。
2.2 关键依赖安装
我们需要添加以下核心依赖:
bash复制yarn add --dev @nomicfoundation/hardhat-toolbox @openzeppelin/contracts dotenv
- @nomicfoundation/hardhat-toolbox:集成了常用插件
- @openzeppelin/contracts:包含ERC-20标准实现
- dotenv:用于管理环境变量
2.3 网络配置
在项目根目录创建.env文件存储敏感信息:
code复制POLKADOT_HUB_URL=https://rpc.polkadot-hub.io
PRIVATE_KEY=你的钱包私钥
然后修改hardhat.config.js:
javascript复制require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config();
module.exports = {
solidity: "0.8.20",
networks: {
polkadotHub: {
url: process.env.POLKADOT_HUB_URL,
accounts: [process.env.PRIVATE_KEY]
}
}
};
警告:永远不要将私钥直接提交到版本控制!确保.gitignore包含.env
3. ERC-20合约开发
3.1 基础合约创建
在contracts目录下创建MyToken.sol:
solidity复制// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MyToken is ERC20 {
constructor(uint256 initialSupply) ERC20("MyToken", "MTK") {
_mint(msg.sender, initialSupply);
}
}
这个基础实现:
- 继承OpenZeppelin的ERC20标准合约
- 设置代币名称为"MyToken",符号为"MTK"
- 在部署时将初始供应量铸造给部署者
3.2 进阶功能扩展
实际项目中你可能需要添加更多功能:
solidity复制import "@openzeppelin/contracts/access/Ownable.sol";
contract MyToken is ERC20, Ownable {
uint256 public constant MAX_SUPPLY = 1000000 * 10**18;
constructor() ERC20("MyToken", "MTK") {
_mint(msg.sender, MAX_SUPPLY);
}
function burn(uint256 amount) public {
_burn(msg.sender, amount);
}
function mint(address to, uint256 amount) public onlyOwner {
require(totalSupply() + amount <= MAX_SUPPLY, "Exceeds max supply");
_mint(to, amount);
}
}
这个增强版增加了:
- 代币最大供应量限制
- 销毁功能
- 仅所有者可调用的铸造功能
- 所有权管理
4. 测试与验证
4.1 编写单元测试
在test目录下创建MyToken.test.js:
javascript复制const { expect } = require("chai");
const { ethers } = require("hardhat");
describe("MyToken", function () {
let MyToken, myToken, owner, addr1;
beforeEach(async function () {
[owner, addr1] = await ethers.getSigners();
MyToken = await ethers.getContractFactory("MyToken");
myToken = await MyToken.deploy();
await myToken.deployed();
});
it("Should have correct name and symbol", async function () {
expect(await myToken.name()).to.equal("MyToken");
expect(await myToken.symbol()).to.equal("MTK");
});
it("Should mint initial supply to owner", async function () {
const ownerBalance = await myToken.balanceOf(owner.address);
expect(await myToken.totalSupply()).to.equal(ownerBalance);
});
it("Should transfer tokens between accounts", async function () {
await myToken.transfer(addr1.address, 100);
expect(await myToken.balanceOf(addr1.address)).to.equal(100);
});
});
运行测试:
bash复制npx hardhat test
4.2 本地网络测试
Hardhat内置本地网络,非常适合快速验证:
bash复制npx hardhat node
在另一个终端部署合约:
bash复制npx hardhat run scripts/deploy.js --network localhost
5. 部署到Polkadot Hub
5.1 准备部署脚本
创建scripts/deploy.js:
javascript复制async function main() {
const [deployer] = await ethers.getSigners();
console.log("Deploying contracts with the account:", deployer.address);
const MyToken = await ethers.getContractFactory("MyToken");
const myToken = await MyToken.deploy();
console.log("MyToken address:", myToken.address);
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
5.2 执行部署
确保你的钱包有足够的DOT用于支付gas费:
bash复制npx hardhat run scripts/deploy.js --network polkadotHub
成功部署后,控制台会输出合约地址。记下这个地址,它将用于后续交互。
5.3 验证合约
为了在区块浏览器上验证合约源码:
- 安装hardhat-etherscan插件:
bash复制yarn add --dev @nomiclabs/hardhat-etherscan
- 更新hardhat.config.js:
javascript复制require("@nomiclabs/hardhat-etherscan");
module.exports = {
// ...其他配置
etherscan: {
apiKey: {
polkadotHub: "你的API_KEY"
},
customChains: [
{
network: "polkadotHub",
chainId: 1234, // Polkadot Hub的chainId
urls: {
apiURL: "https://api.polkadot-hub.io/api",
browserURL: "https://polkadot-hub.io"
}
}
]
}
};
- 运行验证命令:
bash复制npx hardhat verify --network polkadotHub <合约地址>
6. 前端集成与交互
6.1 设置前端项目
使用React创建基础前端:
bash复制npx create-react-app mytoken-frontend
cd mytoken-frontend
yarn add ethers @web3-react/core @web3-react/injected-connector
6.2 连接Polkadot Hub
创建src/web3.js:
javascript复制import { InjectedConnector } from '@web3-react/injected-connector';
import { Web3Provider } from '@ethersproject/providers';
export const injected = new InjectedConnector({
supportedChainIds: [1234] // Polkadot Hub的chainId
});
export function getLibrary(provider) {
return new Web3Provider(provider);
}
6.3 合约交互示例
在React组件中使用合约:
javascript复制import { useWeb3React } from '@web3-react/core';
import { injected } from './web3';
import { Contract } from 'ethers';
import MyTokenABI from './MyTokenABI.json';
function App() {
const { active, account, library, activate } = useWeb3React();
const [balance, setBalance] = useState('0');
const connectWallet = async () => {
try {
await activate(injected);
} catch (e) {
console.error(e);
}
};
const getBalance = async () => {
if (!account) return;
const contract = new Contract(
'0xYourContractAddress',
MyTokenABI,
library.getSigner()
);
const bal = await contract.balanceOf(account);
setBalance(ethers.utils.formatEther(bal));
};
// ...其他交互逻辑
}
7. 高级主题与优化
7.1 Gas优化技巧
Polkadot Hub的EVM实现有其特殊性,以下优化策略特别有效:
- 使用打包交易:将多个操作合并为一个交易
- 合理设置gasPrice:监控网络当前gas价格
- 合约代码优化:
- 使用固定大小数组代替动态数组
- 减少存储操作
- 使用external而非public函数
7.2 跨链考虑
Polkadot Hub的优势在于跨链能力,你可以:
- 通过XCMP与其他平行链交互
- 使用Polkadot的资产桥接功能
- 考虑实现多链代币标准
7.3 安全最佳实践
- 使用OpenZeppelin的Security Contact进行安全审查
- 实现暂停功能(Pausable)
- 设置合理的权限控制
- 进行全面的单元测试和模糊测试
8. 常见问题排查
8.1 部署失败
问题:交易被拒绝或超时
- 检查网络配置是否正确
- 确认账户有足够余额支付gas费
- 尝试增加gasLimit和gasPrice
8.2 合约交互无响应
问题:前端调用合约方法无反应
- 确认MetaMask等钱包已连接到Polkadot Hub网络
- 检查合约ABI是否与部署版本匹配
- 确认调用账户有足够代币余额
8.3 验证失败
问题:合约验证不成功
- 确保编译时的Solidity版本与部署时一致
- 检查构造函数参数是否正确
- 尝试使用--force选项强制重新验证
9. 后续开发建议
完成基础部署后,你可以考虑:
- 添加代币经济模型(质押、回购等)
- 实现DAO治理功能
- 开发配套的DEX流动性池
- 集成到现有DeFi协议中
我在实际部署过程中发现,Polkadot Hub的EVM实现与以太坊主网有细微差别,特别是在gas计算和事件日志方面。建议在正式部署前,先在测试网上充分验证所有功能。另外,Hardhat的console.log在Polkadot Hub上可能表现不同,调试时需要注意这一点。
