A complete ERC-20 token implementation using Hardhat v2, featuring modern development tools and best practices for deploying to the Polkadot testnet.
This project demonstrates how to create, deploy, and test an ERC-20 token contract using Hardhat. The token implementation includes standard ERC-20 functionality plus minting capabilities and owner controls.
The MyToken contract implements:
- ERC-20 Standard: Full compliance with the ERC-20 token standard
- Minting: Owner can mint new tokens to any address
- ERC-20 Permit: Gasless approvals using cryptographic signatures
- Ownable: Access control with owner-only functions
- OpenZeppelin: Built using audited, battle-tested contracts
- Name: MyToken
- Symbol: MTK
- Decimals: 18 (standard)
- Total Supply: Controlled by owner (no initial supply, mint as needed)
erc20-hardhat/
├── contracts/
│ └── MyToken.sol # Main ERC-20 token contract
├── test/
│ └── MyToken.test.ts # Mocha/Chai tests
├── ignition/
│ └── modules/
│ └── MyToken.ts # Deployment configuration
├── artifacts/ # Compiled contracts (auto-generated)
├── cache/ # Hardhat cache (auto-generated)
├── typechain-types/ # TypeScript types (auto-generated)
├── hardhat.config.ts # Hardhat configuration
├── package.json # Project dependencies
├── tsconfig.json # TypeScript configuration
└── README.md # This file
npm installnpx hardhat compileRun tests against the Polkadot testnet:
npm run test:polkadotOr run tests on the default Hardhat network:
npm testDeploy to Hardhat's built-in network:
npx hardhat ignition deploy ignition/modules/MyToken.tsThe project is configured to work with Hardhat's built-in network by default. Simply run:
npx hardhat ignition deploy ignition/modules/MyToken.tsThis will:
- Deploy the MyToken contract
- Set the first account as the owner
- Mint 5 MTK tokens to the owner address
To deploy to the Polkadot testnet, you need an account with funds to send the transaction. The Hardhat configuration uses Configuration Variables for secure private key management.
-
Set your private key:
npx hardhat vars set TESTNET_PRIVATE_KEYYou'll be prompted to enter your private key securely. The value is encrypted and stored locally.
-
(Optional) Set a custom network URL:
npx hardhat vars set TESTNET_URLIf not set, defaults to
http://127.0.0.1:8545 -
Verify your configuration:
npx hardhat vars list
npx hardhat ignition deploy ignition/modules/MyToken.ts --network polkadotTestnetNote: If you get an error about pending transactions, wait a minute for previous transactions to be confirmed (they need 5 confirmations), then try again.
Hardhat Configuration Variables provide secure, encrypted storage for sensitive data:
TESTNET_PRIVATE_KEY: Your private key for deployment (required)TESTNET_URL: Custom RPC endpoint (optional, defaults tohttp://127.0.0.1:8545)
Useful Commands:
# Set a variable (will prompt for value)
npx hardhat vars set TESTNET_PRIVATE_KEY
# List all variables
npx hardhat vars list
# View a variable
npx hardhat vars get TESTNET_PRIVATE_KEY
# Delete a variable
npx hardhat vars delete TESTNET_PRIVATE_KEY
# See storage location
npx hardhat vars pathThe project includes the following networks:
- hardhat: Built-in Hardhat network (default)
- polkadotTestnet: Local Polkadot testnet node at
http://127.0.0.1:8545
npx hardhat console --network localhost// Get the deployed contract
const MyToken = await ethers.getContractFactory("MyToken");
const token = await MyToken.attach("DEPLOYED_CONTRACT_ADDRESS");
// Check token details
await token.name(); // "MyToken"
await token.symbol(); // "MTK"
await token.decimals(); // 18
// Mint tokens (only owner)
await token.mint("0x...", ethers.parseEther("100"));
// Check balance
await token.balanceOf("0x...");This project uses modern Ethereum development practices:
- Hardhat v2: Stable, production-ready development environment
- TypeScript: Full type safety throughout the project
- Ethers v6: Modern Ethereum library for contract interactions
- Mocha + Chai: Robust testing framework
- TypeChain: Auto-generated TypeScript types for contracts
- OpenZeppelin: Industry-standard smart contract libraries
- Hardhat Ignition: Declarative deployment system
- Configuration Variables: Secure, encrypted key management
The project includes comprehensive TypeScript tests using Mocha and Chai:
- Test File:
test/MyToken.test.ts - Framework: Mocha with Chai assertions
- Features Tested:
- Contract deployment
- Token name, symbol, and decimals
- Owner assignment
- Minting functionality
- Balance tracking
- Total supply updates
Run tests:
# Against Polkadot testnet
npm run test:polkadot
# On Hardhat network
npm test- The contract uses OpenZeppelin's audited implementations
- Owner privileges are clearly defined and limited to minting
- ERC-20 Permit reduces gas costs and improves UX for approvals
- All standard ERC-20 security patterns are implemented
- Hardhat Documentation
- Hardhat Configuration Variables
- OpenZeppelin ERC-20 Documentation
- ERC-20 Permit Explanation
- Ethers.js Documentation
Contributions are welcome! Please ensure:
- All tests pass
- Code follows the existing style
- New features include appropriate tests
- Documentation is updated as needed
This project is licensed under the MIT License.