Skip to main content
In this tutorial, you’ll deploy, mint, and burn ERC‑721 tokens (NFTs) using Foundry and OpenZeppelin on the Hedera Testnet. You’ll set up a Foundry project, write an ERC‑721 contract, deploy it via a Foundry script, mint an NFT to your account, add burn functionality, and burn an NFT. We’ll connect to Hedera via the JSON‑RPC relay (Hashio) and use Foundry tools:
  • forge: build and deploy through scripts
  • cast: quick RPC interactions
You can take a look at the complete code in the Hedera-Code-Snippets repository.

Prerequisites

  • Foundry installed (forge, cast, anvil, chisel):
    • curl -L https://foundry.paradigm.xyz | bash
    • foundryup
  • ECDSA account and 0x‑prefixed private key for Hedera Testnet (create/fund via the Hedera Portal)
  • Basic Solidity / CLI familiarity

Table of Contents

  1. Step 1: Project Setup
  2. Step 2: Creating the ERC-721 Contract
  3. Step 3: Deploy your ERC-721 Smart Contract
  4. Step 4: Minting an NFT
  5. Step 5: Adding the Burn Functionality
  6. Step 6: Burning an NFT
  7. Step 7: Run tests(Optional)
  8. Interacting with the Contract using “cast”

Step 1: Project Setup

Initialize Project

Set up your project by initializing the hardhat project:
This creates a new directory with a standard Foundry project structure, including src, test, and script folders.

Install Dependencies

Foundry uses git submodules to manage dependencies. We’ll install the OpenZeppelin Contracts library, which provides a standard and secure implementation of the ERC20 token.
This command will download the contracts and add them to your lib folder. Create .env File Create an .env for your RPC URL and private key.
Put the following into your environment file.
.env
Now, let’s also load these to the terminal:
Replace the 0x-your-private-key environment variable with the HEX Encoded Private Key for your ECDSA account from the Hedera Portal
Please note: that Hashio is intended for development and testing purposes only. For production use cases, it’s recommended to use commercial-grade JSON-RPC Relay or host your own instance of the Hiero JSON-RPC Relay.

Configure Foundry

Update your foundry.toml file in the root directory of your project. Open it and add profiles for the Hedera Testnet RPC endpoint.
foundry.toml
Note the values in remappings field. We need this to import prefix to a filesystem path so both Foundry(forge) and our editor can resolve short, package-like imports instead of long relative paths. We will be removing the default contracts that comes with foundry default project:

Step 2: Creating the ERC-721 Contract

Create a new Solidity file (MyToken.sol) in our contracts directory:
src/MyToken.sol
This contract was created using the OpenZeppelin Contracts Wizard and OpenZeppelin’s ERC-721 standard implementation with an ownership model. The ERC-721 token’s name has been set to “MyToken.” The contract implements the safeMint function, which accepts the address of the owner of the new token and uses auto-increment IDs, starting from 0. Let’s compile this contract by running:
This command will generate the smart contract artifacts, including the ABI. We are now ready to deploy the smart contract.

Step 3: Deploy Your ERC-721 Smart Contract

Create a deployment script (DeployMyToken.s.sol) in script directory:
script/DeployMyToken.s.sol
In this script, we first retrieve your account (the deployer) that’s on our .env file. This account will own the deployed smart contract. Next, we use this account to deploy the contract by calling MyToken.deploy(deployerAddress). This passes your account address as the initial owner and signer of the deployment transaction. Deploy your contract by executing the script:
After a few moments, you will see the address of your newly deployed contract:
Note that Foundry hardcodes “ETH” in its summary. However, even if it says ETH, because we’re connected to Hedera, the currency used is HBAR.
Next, set up variables for your contract address and public address to make the next commands easier to read. Please export these variables in your shell.
Let’s also verify our contract because it is so easy to do so and it is good practice. Verification submits the source code to Sourcify, which natively supports Hedera Testnet (chain ID 296); the verified status will then appear on HashScan.

Step 4: Minting an NFT

We will now create a new file MintMyToken.s.sol script in our script directory to mint an NFT. Don’t forget to replace the <your-contract-address> with the address you’ve just copied.
script/MintMyToken.s.sol
The code mints a new NFT to your account ( deployer.address ). Then we verify the balance to see if we own an ERC-721 token of type MyToken. Mint an NFT:
Expected output:

Step 5: Adding the Burn Functionality

Update your contract to add NFT burning capability by importing the burnable extension and adding it to the interfaces list for your contract:
Redeploy:
Reverify:
Copy the new smart contract address and replace the address in the script/MintMyToken.s.sol script with your new address. Let’s mint a new NFT for the redeployed contract:

Step 6: Burning an NFT

Create a burn script (BurnMyToken.s.sol ) in your script directory. Don’t forget to replace the <your-contract-address> with your own contract address and <your-token-id> with the token Id you want to burn(eg. 0).
script/BurnMyToken.s.sol
The script will burn the ERC-721 token with the ID set to 1, which is the ERC-721 token you’ve just minted. To be sure the token has been deleted, let’s print the balance for our account to the terminal. The balance should show a balance of 0. Burn the NFT:
Expected output:
Congratulations! 🎉 You have successfully learned how to deploy an ERC-721 smart contract using Foundry and OpenZeppelin. Feel free to reach out in Discord!

Step 7: Run tests(Optional)

You can find both types of tests in the Hedera-Code-Snippets repository. You will find the following files:
  • test/MyToken.t.sol
Copy this file and then run the tests:
To deep dive into how to write these tests from scratch, go to the section under “How to Write Tests in Solidity (Part 2)”.

Interacting with the Contract using “cast”(Optional - Advanced)

Apart from interacting with the contract using dedicated scripts like MintMyToken.s.sol or BurnMyToken.s.sol, we can also use cast, Foundry’s command-line tool for doing the exact same thing by making RPC calls. We are going to deploy the contract using cast in this section but you should be able to able to perform any other operation such as mint or burn using cast as well(even though it might be a little bit more complicated to do so). To use cast and other command-line tools, you need to load the variables from your .env file into your current terminal session.

Environment Setup

Run the following command to load the HEDERA_PRIVATE_KEY and HEDERA_RPC_URL into your shell. In addition, we will derive our address and save it to MY_ADDRESS.
Please make sure to have jq installed on your machine for the following exercises. You can learn more about it on the official jq site.

Compile and fetch creation bytecode

We’ll use forge to inspect the creation bytecode of MyToken and cast to encode constructor args.

Deploy the contract with cast

cast will submit a contract creation transaction. Then we’ll fetch the receipt and extract the deployed contract address.

Further Learning & Next Steps

Want to take your local development setup even further? Here are some excellent tutorials to help you dive deeper into smart contract development on Hedera using Foundry:
  1. How to Write Tests in Solidity (Part 2)
    Learn how to start writing tests in Foundry using Solidity
  2. How to Fork the Hedera Network for Local Testing
    Learn how to fork hedera network(testnet/mainnet) locally so you can start testing against the forked network

Writer: Kiran, Developer Advocate

Editor: Luke, DevRel Engineer

Editor: Krystal, Senior DX Engineer