---
# System prepended metadata

title: 'Week 14 at Blockfuse Labs: My Journey with Foundry, Building a School Management System and an NFT Marketplace'

---




# Week 14 at Blockfuse Labs: My Journey with Foundry, Building a School Management System and an NFT Marketplace

When I first heard about **Foundry**, I thought, *“Here w**Blockfuse Labs** changed that. Instead of feeling overwhelmed, I discovered how powerful Foundry is — not just for writing smart contracts, but for testing, debugging, and deploying them faster than I imagined.

This week, I built two projects that pushed me out of my comfort zone:

1. A **School Management System** smart contract.
2. An **NFT Marketplace** where people could mint, buy, and sell NFTs.

It was one of the most exciting weeks so far.



## Discovering Foundry

Foundry is like having a turbo engine for smart contract development. It comes with two main tools:

* **Forge** → for building, testing, and deploying contracts.
* **Cast** → for sending transactions and reading data from contracts.

Here are the basic commands I learned:

### Foundry Setup Commands

```bash
forge init myProject       # Create a new project
forge build                # Compile contracts
forge test                 # Run all tests
forge test -vvv            # Run tests with detailed logs
forge clean                # Clear build cache
forge install OpenZeppelin/openzeppelin-contracts  # Install dependencies
forge update               # Update dependencies
```

### Cast Commands

```bash
cast call <address> "<functionSignature>" <args>   # Call a contract function
cast send <address> "<functionSignature>" <args>   # Send a transaction
cast block-number                                  # Get current block number
cast balance <address>                             # Get ETH balance
```



## Project 1: School Management System

I revisited the **School Management System** idea from earlier weeks but rebuilt it in Foundry.

### Features I implemented:

* **Admin** can register students.
* **Admin** can assign grades.
* Students’ data (name + grade) is stored on-chain.

### Smart Contract Example

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract School {
    address public admin;

    struct Student {
        string name;
        uint grade;
    }

    mapping(address => Student) public students;

    constructor() {
        admin = msg.sender;
    }

    function registerStudent(address student, string memory name) external {
        require(msg.sender == admin, "Only admin can register");
        students[student] = Student(name, 0);
    }

    function assignGrade(address student, uint grade) external {
        require(msg.sender == admin, "Only admin can assign grades");
        students[student].grade = grade;
    }
}
```



## Writing Tests in Foundry

The beauty of Foundry is that you write tests directly in Solidity.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

import "forge-std/Test.sol";
import "../src/School.sol";

contract SchoolTest is Test {
    School school;
    address admin = address(this);
    address student = address(0xBEEF);

    function setUp() public {
        school = new School();
    }

    function testRegisterStudent() public {
        school.registerStudent(student, "Alice");
        (string memory name, uint grade) = school.students(student);
        assertEq(name, "Alice");
        assertEq(grade, 0);
    }

    function testOnlyAdminCanRegister() public {
        vm.prank(address(0xCAFE)); // impersonate another account
        vm.expectRevert();
        school.registerStudent(student, "Bob");
    }
}
```

### Useful Foundry Cheatcodes (via `vm`)

* `vm.prank(addr)` → impersonates another account.
* `vm.expectRevert()` → expect a function to fail.
* `vm.warp(timestamp)` → fast-forward time.
* `vm.deal(addr, amount)` → give ETH to an account.
* `vm.roll(blockNumber)` → set block number.
* `vm.snapshot()` / `vm.revert(snapshotId)` → save and restore blockchain state.

---

## Project 2: NFT Marketplace

After the school system, I built an **NFT Marketplace**.

### Features:

* Users can mint NFTs.
* Owners can list NFTs for sale.
* Buyers can purchase NFTs.

### Contract Example

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract NFTMarket is ERC721 {
    uint public nextTokenId;
    address public admin;

    struct Listing {
        uint tokenId;
        uint price;
        address seller;
    }

    mapping(uint => Listing) public listings;

    constructor() ERC721("MyNFT", "MNFT") {
        admin = msg.sender;
    }

    function mint(address to) external {
        _safeMint(to, nextTokenId);
        nextTokenId++;
    }

    function list(uint tokenId, uint price) external {
        require(ownerOf(tokenId) == msg.sender, "Not owner");
        listings[tokenId] = Listing(tokenId, price, msg.sender);
    }

    function buy(uint tokenId) external payable {
        Listing memory listing = listings[tokenId];
        require(msg.value == listing.price, "Incorrect price");
        _transfer(listing.seller, msg.sender, tokenId);
        payable(listing.seller).transfer(msg.value);
        delete listings[tokenId];
    }
}
```

## Testing the Marketplace in Foundry

```solidity
pragma solidity ^0.8.17;

import "forge-std/Test.sol";
import "../src/NFTMarket.sol";

contract NFTMarketTest is Test {
    NFTMarket market;
    address alice = address(0xABCD);
    address bob = address(0x1234);

    function setUp() public {
        market = new NFTMarket();
    }

    function testMintAndListNFT() public {
        vm.prank(alice);
        market.mint(alice);

        vm.prank(alice);
        market.list(0, 1 ether);

        (uint tokenId, uint price, address seller) = market.listings(0);
        assertEq(tokenId, 0);
        assertEq(price, 1 ether);
        assertEq(seller, alice);
    }

    function testBuyNFT() public {
        vm.deal(alice, 1 ether);
        vm.deal(bob, 2 ether);

        vm.prank(alice);
        market.mint(alice);

        vm.prank(alice);
        market.list(0, 1 ether);

        vm.prank(bob);
        market.buy{value: 1 ether}(0);

        assertEq(market.ownerOf(0), bob);
    }
}
```

---

## Foundry Commands I Used for This Project

Here’s the cheat sheet of commands that carried me through Week 14:

### Compilation & Testing

```bash
forge build            # Compile contracts
forge test             # Run tests
forge test -vvv        # Run tests with detailed logs
forge test --match-test testBuyNFT   # Run a single test
```

### Gas Reporting

```bash
forge test --gas-report   # Run tests and show gas usage
```

### Coverage

```bash
forge coverage         # Check test coverage
```

### Deployments

```bash
forge script script/Deploy.s.sol --rpc-url <RPC_URL> --private-key <KEY> --broadcast
```

### Cast Utilities

```bash
cast balance <address>                   # Get ETH balance
cast call <address> "ownerOf(uint256)" 0 # Read NFT owner
cast send <address> "mint(address)" <to> --private-key <KEY> --rpc-url <RPC_URL>
```

---

## Summary Of Week 14

By the end of the week, I realized:

1. **Foundry is lightning-fast** — no waiting for TypeScript, just Solidity tests running instantly.
2. **Cheatcodes give control** — I could impersonate accounts, fast-forward time, or fund wallets.
3. **Testing = confidence** — I could simulate real-world scenarios (students registering, NFTs being bought) safely.
4. **Commands matter** — Foundry’s simplicity comes from its CLI. Once you memorize `forge build`, `forge test`, and `cast call`, you feel unstoppable.

---

## Looking Ahead

Week 14 made me feel like I unlocked a new level of blockchain development. With Foundry, I don’t just write contracts — I **test them deeply**, **analyze gas usage**, and **interact with them live** using Cast.

Next, I want to try:

* **Property-based testing** (`forge fuzz`) to check random inputs.
* **Mainnet forking** (`--fork-url`) to simulate real Ethereum conditions.

For now, I’m just happy that I built a **school on-chain** and a **marketplace for NFTs** — and proved they worked, line by line, with Foundry.
