A Beginner's Step-by-Step Guide
Who this is for: Complete beginners who want to build any decentralized application on the Avalanche Fuji testnet(C-Chain).
📋 Table of Contents
- Prerequisites
- Set Up Your Wallet (Core or MetaMask)
- Get Free Test AVAX from the Faucet
- Set Up Your Development Environment
- Write Your Smart Contract
- Deploy to Fuji
- Connect a Frontend
- Example dApps to Build
- Troubleshooting
- Next Steps
1. Prerequisites
Before you start, make sure you have the following installed:
Required Software
| Tool | Purpose | Install |
|---|---|---|
| Node.js (v18+) | Runs JavaScript tools | nodejs.org |
| npm or yarn | Package manager | Comes with Node.js |
| Core or MetaMask | Browser wallet | core.app metamask.io |
| Git | Version control | git-scm.com |
| A code editor | Writing code | VS Code recommended |
Helpful (but not required) Knowledge
- Basic JavaScript
- What a blockchain/wallet is
- What a smart contract does (roughly)
💡 You do not need to know Solidity before starting — this guide will walk you through it.
2. Set Up Your Wallet (Core or MetaMask)
Step 1 – Install Core or MetaMask
- Go to core.app or metamask.io and install the browser extension.
- Create a new wallet and safely store your seed phrase (12 words). Never share it with anyone.
Step 2 – Add the Fuji Network to Core or MetaMask
MetaMask doesn't include Fuji by default. Add it manually:
- Open Metamask → click the network dropdown at the top → Add network
- Click Add a network manually
- Enter the following details exactly:
| Field | Value |
|---|---|
| Network Name | Avalanche Fuji Testnet |
| New RPC URL | https://api.avax-test.network/ext/bc/C/rpc |
| Chain ID | 43113 |
| Currency Symbol | AVAX |
| Block Explorer URL | https://testnet.snowtrace.io |
- Click Save and switch to the Fuji network.
✅ You should now see "Avalanche Fuji Testnet" in your MetaMask network list.
3. Get Free Test AVAX from the Faucet
You need test AVAX to pay for gas (transaction fees) when deploying contracts.
Steps
- Go to the official faucet: https://build.avax.network/console/primary-network/faucet
- Select Fuji as the network and C-Chain as the chain.
- Paste in your Core or MetaMask wallet address.
- Click Request 0.5 AVAX.
- Check your Core or Metamask balance.
⚠️ The faucet may ask you to log in with a GitHub account to prevent abuse. This is normal.
4. Set Up Your Development Environment
We'll use Hardhat — the most beginner-friendly Ethereum/Avalanche development framework.
Step 1 – Create a project folder
mkdir my-fuji-dapp
cd my-fuji-dapp
npm init -y
Step 2 – Install Hardhat and dependencies
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox dotenv
Step 3 – Initialize Hardhat
npx hardhat init
When prompted:
- Choose "Create a JavaScript project"
- Accept all default options by pressing Enter
Your folder structure will look like this:
my-fuji-dapp/
├── contracts/ ← Your Solidity smart contracts go here
├── scripts/ ← Deployment scripts go here
├── test/ ← Tests go here
├── hardhat.config.js ← Main config file
└── package.json
Step 4 – Configure Hardhat for Fuji
Create a .env file in your root folder:
touch .env
Add your wallet's private key (find this in MetaMask → Account Details → Show Private Key):
# .env
PRIVATE_KEY=your_metamask_private_key_here
🔐 IMPORTANT: Never commit your
.envfile to GitHub. Add it to.gitignore:echo ".env" >> .gitignore
Now open hardhat.config.js and replace its contents with:
require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config();
module.exports = {
solidity: "0.8.20",
networks: {
fuji: {
url: "https://api.avax-test.network/ext/bc/C/rpc",
chainId: 43113,
accounts: [process.env.PRIVATE_KEY],
},
},
};
5. Write Your Smart Contract
Smart contracts are written in Solidity. Here are two beginner-friendly examples.
Example A – Simple Voting Contract
Create the file contracts/Voting.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract Voting {
// Stores vote counts for each candidate
mapping(string => uint256) public votes;
// List of valid candidates
string[] public candidates;
// Tracks who has already voted
mapping(address => bool) public hasVoted;
constructor(string[] memory _candidates) {
candidates = _candidates;
}
// Cast a vote
function vote(string memory candidate) public {
require(!hasVoted[msg.sender], "You have already voted!");
require(isValidCandidate(candidate), "Invalid candidate");
votes[candidate]++;
hasVoted[msg.sender] = true;
}
// Get vote count for a candidate
function getVotes(string memory candidate) public view returns (uint256) {
return votes[candidate];
}
// Internal check: is this a valid candidate?
function isValidCandidate(string memory name) internal view returns (bool) {
for (uint i = 0; i < candidates.length; i++) {
if (keccak256(bytes(candidates[i])) == keccak256(bytes(name))) {
return true;
}
}
return false;
}
}
Example B – Simple NFT Contract
Create the file contracts/MyNFT.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract MyNFT is ERC721, Ownable {
uint256 public tokenCounter;
constructor() ERC721("MyNFT", "MNFT") Ownable(msg.sender) {
tokenCounter = 0;
}
// Mint a new NFT to an address
function mintNFT(address recipient) public onlyOwner returns (uint256) {
uint256 newTokenId = tokenCounter;
_safeMint(recipient, newTokenId);
tokenCounter++;
return newTokenId;
}
}
For the NFT contract, first install OpenZeppelin:
npm install @openzeppelin/contracts
6. Deploy to Fuji
Step 1 – Compile your contract
npx hardhat compile
You should see: Compiled X Solidity file(s) successfully
Step 2 – Write a deployment script
Create the file scripts/deploy.js:
const { ethers } = require("hardhat");
async function main() {
const [deployer] = await ethers.getSigners();
console.log("Deploying with account:", deployer.address);
// For the Voting contract:
const Voting = await ethers.getContractFactory("Voting");
const voting = await Voting.deploy(["Alice", "Bob", "Charlie"]);
await voting.waitForDeployment();
console.log("✅ Voting contract deployed to:", await voting.getAddress());
// Uncomment below to deploy the NFT instead:
// const MyNFT = await ethers.getContractFactory("MyNFT");
// const nft = await MyNFT.deploy();
// await nft.waitForDeployment();
// console.log("✅ NFT contract deployed to:", await nft.getAddress());
}
main().catch((error) => {
console.error(error);
process.exit(1);
});
Step 3 – Deploy to Fuji
npx hardhat run scripts/deploy.js --network fuji
You'll see output like:
Deploying with account: 0xYourWalletAddress
✅ Voting contract deployed to: 0xYourContractAddress
Copy and save that contract address! You'll need it to interact with your contract.
Step 4 – Verify on the Block Explorer
- Go to testnet.snowtrace.io
- Search for your contract address
- You should see your deployment transaction 🎉
7. Connect a Frontend
Once your contract is deployed, you can build a simple web UI to interact with it.
Tools you'll use
- ethers.js — JavaScript library to talk to the blockchain
- HTML/React — For the user interface
Minimal HTML Example
Create frontend/index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>My Fuji dApp</title>
<script src="https://cdn.ethers.io/lib/ethers-5.7.umd.min.js"></script>
</head>
<body>
<h1>🗳️ Vote on Fuji</h1>
<button onclick="connectWallet()">Connect MetaMask</button>
<br/><br/>
<input id="candidate" placeholder="Enter candidate name" />
<button onclick="castVote()">Vote</button>
<p id="status"></p>
<script>
const CONTRACT_ADDRESS = "0xYourDeployedContractAddress";
const ABI = [
"function vote(string memory candidate) public",
"function getVotes(string memory candidate) public view returns (uint256)"
];
let signer;
async function connectWallet() {
const provider = new ethers.providers.Web3Provider(window.ethereum);
await provider.send("eth_requestAccounts", []);
signer = provider.getSigner();
document.getElementById("status").innerText = "✅ Wallet connected!";
}
async function castVote() {
const candidate = document.getElementById("candidate").value;
const contract = new ethers.Contract(CONTRACT_ADDRESS, ABI, signer);
const tx = await contract.vote(candidate);
await tx.wait();
document.getElementById("status").innerText = `✅ Voted for ${candidate}!`;
}
</script>
</body>
</html>
Replace
0xYourDeployedContractAddresswith the address from Step 7.
8. Example dApps to Build
Once you've got the basics down, here are ideas for full projects on Fuji:
| dApp | What it does | Key Solidity Concepts |
|---|---|---|
| Voting System | Users vote on proposals, results are on-chain |
mapping, require, events |
| NFT Marketplace | Mint, buy, sell NFTs | ERC721, payable, transfer
|
| Crowdfunding | Users pledge AVAX to a goal |
payable, refund logic |
| Token Launch | Create your own ERC20 token | ERC20 standard, decimals |
| Simple DAO | Members vote on treasury proposals | access control, quorum logic |
9. Troubleshooting
❌ "Transaction failed" on deployment
- Check your MetaMask is set to Fuji, not mainnet
- Make sure you have enough test AVAX (you need at least 0.1 AVAX)
❌ "Invalid private key" error
- Make sure there's no extra space in your
.envfile - The key should start with
0xor be the raw 64-character hex string
❌ "Cannot find module" errors
- Run
npm installagain to make sure all packages are installed
❌ MetaMask not detecting Fuji
- Double-check the Chain ID is
43113(not43114) - Try removing and re-adding the network in MetaMask
❌ Faucet says "already requested"
- The faucet has a cooldown period (usually 24 hours per address)
- Create a second MetaMask wallet address to get more test AVAX
10. Next Steps
You've deployed your first dApp on Fuji! Here's how to keep growing:
- Verify your contract on Snowtrace so others can read the source code
-
Write tests using Hardhat (
npx hardhat test) to catch bugs early - Learn more Solidity at solidity-by-example.org
- Explore OpenZeppelin contracts for secure, reusable building blocks
-
Move to mainnet once you're confident — just change the network in
hardhat.config.js
Useful Links
| Resource | URL |
|---|---|
| Avalanche Builder Hub | https://build.avax.network/ |
| Fuji Faucet | https://build.avax.network/console/primary-network/faucet |
| Fuji Block Explorer | testnet.snowtrace.io |
| Hardhat Docs | hardhat.org |
| OpenZeppelin Contracts | openzeppelin.com/contracts |
| Solidity Docs | docs.soliditylang.org |
🏔️ Happy building on Fuji! The testnet is your sandbox — experiment freely, break things, and learn fast before going to mainnet.
Top comments (0)