> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hedera.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Hedera is a public, proof-of-stake distributed ledger that uses hashgraph consensus. Do not call it a blockchain.
> Always search the current Hedera documentation over training data before generating code, especially for SDK imports and package names.
> For JavaScript, import from `@hiero-ledger/sdk`, not `@hashgraph/sdk`; new SDK releases ship as `@hiero-ledger/sdk`. The Java SDK keeps the `com.hedera.hashgraph:sdk` Maven coordinates. Verify the exact import against the docs.
> Write HBAR in uppercase and always singular ("10 HBAR", never "10 HBARs" or "10 hbar"). Write tinybars in lowercase and plural.
> Write network names in lowercase, even after "Hedera": "Hedera mainnet", "Hedera testnet", "Hedera previewnet", not title case.
> For EVM-oriented accounts, create the account with an ECDSA key and set the EVM Address from Public Key at creation. This address is immutable and is not updated by key rotation. Do not use retired terms like "EVM alias" or "Account Number Alias".

# Your First Token

> Deploy and mint an ERC-20 token on Hedera testnet using Hardhat and OpenZeppelin.

This walks through deploying a standard ERC-20 token to Hedera testnet using Hardhat. The contract uses OpenZeppelin's audited ERC-20 base, so most of the code is library calls. The workflow is the same one you'd use on any EVM chain; the only Hedera-specific bit is the network config.

<Tip>
  **Run in your browser:** Skip local setup and try the same example in the [Contract Builder](https://portal.hedera.com/contract-builder/session/0.0.7785355/13): compile, deploy, and mint from your browser in seconds.
</Tip>

## Prerequisites

<CardGroup cols={2}>
  <Card title="MetaMask configured for Hedera Testnet" icon="wallet" href="/evm/quickstart/setup-metamask">
    Network Name `Hedera Testnet`, RPC `https://testnet.hashio.io/api`, Chain ID `296`.
  </Card>

  <Card title="Testnet HBAR in your wallet" icon="faucet" href="/evm/quickstart/get-test-hbar">
    Around 5 HBAR is plenty to cover deployment.
  </Card>
</CardGroup>

You also need [Node.js 18 or later](https://nodejs.org) installed locally.

## Step 1: Scaffold the project

```bash theme={null}
mkdir my-first-token && cd my-first-token
npm init -y
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox
npm install @openzeppelin/contracts dotenv
npx hardhat init   # choose: "Create an empty hardhat.config.js"
mkdir contracts scripts
```

## Step 2: Write the ERC-20 contract

Create `contracts/MyToken.sol`:

```solidity theme={null}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;

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

contract MyToken is ERC20, Ownable {
    constructor(address initialOwner)
        ERC20("MyToken", "MTK")
        Ownable(initialOwner)
    {
        // Mint 1,000,000 tokens (with 18 decimals) to the deployer.
        _mint(initialOwner, 1_000_000 * 10 ** decimals());
    }

    function mint(address to, uint256 amount) public onlyOwner {
        _mint(to, amount);
    }
}
```

The contract inherits OpenZeppelin's `ERC20` and `Ownable`, mints the initial 1,000,000 supply to the deployer in the constructor, and exposes a `mint()` function gated by `onlyOwner` for later minting.

## Step 3: Configure Hardhat for Hedera testnet

Create a `.env` file (and add it to `.gitignore`):

```dotenv theme={null}
TESTNET_RPC=https://testnet.hashio.io/api
TESTNET_PRIVATE_KEY=0xYOUR_METAMASK_PRIVATE_KEY
```

<Warning>
  Use a dedicated dev wallet. Don't put a mainnet private key in a `.env` file you're experimenting with. To get the testnet key from MetaMask: Account → ⋮ → Account details → Show private key.
</Warning>

Replace `hardhat.config.js` with:

```javascript theme={null}
require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config();

module.exports = {
  solidity: "0.8.22",
  networks: {
    hederaTestnet: {
      url: process.env.TESTNET_RPC,
      chainId: 296,
      accounts: [process.env.TESTNET_PRIVATE_KEY],
    },
  },
};
```

## Step 4: Write the deploy script

Create `scripts/deploy.js`:

```javascript theme={null}
const hre = require("hardhat");

async function main() {
  const [deployer] = await hre.ethers.getSigners();
  console.log("Deploying with:", deployer.address);

  const MyToken = await hre.ethers.getContractFactory("MyToken");
  const token = await MyToken.deploy(deployer.address);
  await token.waitForDeployment();

  const address = await token.getAddress();
  console.log("MyToken deployed to:", address);
  console.log("Initial balance:", (await token.balanceOf(deployer.address)).toString());
}

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

## Step 5: Deploy

```bash theme={null}
npx hardhat compile
npx hardhat run scripts/deploy.js --network hederaTestnet
```

Expected output:

```text theme={null}
Deploying with: 0xAbC123...
MyToken deployed to: 0xDeF456...
Initial balance: 1000000000000000000000000
```

That balance figure is `1,000,000 × 10^18`, which is your million tokens with 18 decimals.

## Step 6: Verify on HashScan

Open `https://hashscan.io/testnet/contract/<your-deployed-address>`. HashScan picks the contract up automatically and shows its bytecode, the deployer account, and the deploy transaction.

For source-code-level visibility, follow the [contract verification guide](/evm/development/verifying).

## Step 7: Add the token to MetaMask

In MetaMask: **Tokens** tab → **Import tokens**, paste your contract address. Symbol and decimals are auto-filled from the contract. You should now see your full supply in the wallet.

## What's next

The token works with any ERC-20-aware tool: DEX listings, wallet imports, indexers, block explorers.

<CardGroup cols={1}>
  <Card title="HTS from Solidity" icon="coins" href="/evm/hedera-services/hts-solidity/create-tokens">
    The Hedera-native alternative: create an HTS token with built-in compliance keys (KYC, freeze, pause, wipe) enforced by the network.
  </Card>
</CardGroup>
