Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Week 4 Solution done #8

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .gitignore
Binary file not shown.
18 changes: 18 additions & 0 deletions 9.1.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

added 809 packages, and audited 845 packages in 2m

143 packages are looking for funding
run `npm fund` for details

57 vulnerabilities (35 low, 7 moderate, 9 high, 6 critical)

To address issues that do not require attention, run:
npm audit fix

To address all issues possible (including breaking changes), run:
npm audit fix --force

Some issues need review, and may require choosing
a different dependency.

Run `npm audit` for details.
130 changes: 8 additions & 122 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,127 +1,13 @@
# 📝 Assignment for Week 4: NFTs and the Metaverse
# Sample Hardhat Project

In this week's assignment, we will work on building a simple NFT contract, setting up Hardhat tasks, and creating test cases to ensure proper functionality. The tasks involve deploying, minting, and interacting with an NFT smart contract, which we'll build using OpenZeppelin and Hardhat.
This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, and a Hardhat Ignition module that deploys that contract.

## Exercise Breakdown
Try running some of the following tasks:


### Exercise 0 : Initialise your Hardhat project

```
mkdir nft-project
cd nft-project
npx hardhat
```

make sure to use `.env` file for sensetive info.


#### IMPORTANT : The given files are just for helping purposes and giving idea of the structure of the project.
This repo contains Demo codes for the files without the depandancies.

### Exercise 1: Create Your Solidity Contract
You will write a simple ERC721-based contract for minting NFTs using OpenZeppelin libraries.

The contract file is located at:

- [contracts/MyNFT.sol](contracts/MyNFT.sol)

### Exercise 2: Create Hardhat Tasks for Deploying and Minting NFTs
We will create tasks to deploy the NFT contract and mint NFTs using Hardhat.

The task file is located at:

- [tasks/nft.ts](tasks/nft.ts)

### Exercise 3: Create Helpers
The helpers for interacting with our contract and environment variables are implemented in the following files:

- [lib/contract.ts](lib/contract.ts)
- [lib/env.ts](lib/env.ts)
- [lib/provider.ts](lib/provider.ts)
- [lib/wallet.ts](lib/wallet.ts)

### Exercise 4: Create Tests
We will write unit and integration tests to validate the NFT contract functionality. The tests will check minting functionality and balance tracking.

Test files:

- [test/MyNFT.spec.ts](test/MyNFT.spec.ts) – Unit tests for the NFT contract.
- [test/tasks.spec.ts](test/tasks.spec.ts) – Integration tests for Hardhat tasks.
- [test/test-helpers.ts](test/test-helpers.ts) – Helpers used in the tests.

### Exercise 5: Hardhat Configuration
We will configure Hardhat to use the Alchemy API and connect to the Sepolia test network.

Configuration file:

- [hardhat.config.ts](hardhat.config.ts)

---

## Useful Commands


- Compile the smart contracts:

```bash
npx hardhat compile
```

- Deploy the contract:

```bash
npx hardhat deploy-contract
```

- Mint an NFT:

```bash
npx hardhat mint-nft --tokenUri "https://example.com/token-metadata"
```

---

## Running Tests

To run the test cases, execute:

```bash
```shell
npx hardhat help
npx hardhat test
REPORT_GAS=true npx hardhat test
npx hardhat node
npx hardhat ignition deploy ./ignition/modules/Lock.js
```

Example output:

```
mintNft
✓ calls through and returns the transaction object (60ms)

MyNFT
mintNft
✓ emits the Transfer event (60ms)
✓ returns the new item ID
✓ increments the item ID (57ms)
✓ cannot mint to address zero
balanceOf
✓ gets the count of NFTs for this address

6 passing (2s)
✨ Done in 5.66s.
```

---

## Resources

- [OpenZeppelin Documentation](https://docs.openzeppelin.com/)
- [Hardhat Documentation](https://hardhat.org/getting-started/)

## What to Submit

- A link to your GitHub Pull Request with the implemented contract and tasks.

- Head over to the Coursework submission link: [Google Form](https://docs.google.com/forms/d/e/1FAIpQLScspmFUymr7wMW9HxjwRSlSa1Zxnnj9H3LJK6Y9xsPeus-iCw/viewform?usp=sf_link) to submit your work.

Inform your UniDAO lead once the submission has been made.

Feel free to ask any questions or seek clarification on Discord.
34 changes: 34 additions & 0 deletions contracts/Lock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.27;

// Uncomment this line to use console.log
// import "hardhat/console.sol";

contract Lock {
uint public unlockTime;
address payable public owner;

event Withdrawal(uint amount, uint when);

constructor(uint _unlockTime) payable {
require(
block.timestamp < _unlockTime,
"Unlock time should be in the future"
);

unlockTime = _unlockTime;
owner = payable(msg.sender);
}

function withdraw() public {
// Uncomment this line, and the import of "hardhat/console.sol", to print a log in your terminal
// console.log("Unlock time is %o and block timestamp is %o", unlockTime, block.timestamp);

require(block.timestamp >= unlockTime, "You can't withdraw yet");
require(msg.sender == owner, "You aren't the owner");

emit Withdrawal(address(this).balance, block.timestamp);

owner.transfer(address(this).balance);
}
}
2 changes: 1 addition & 1 deletion contracts/MyNFT.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ contract MyNFT is ERC721URIStorage {

return newItemId;
}
}
}
1 change: 1 addition & 0 deletions declarations.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
declare module 'sinon';
33 changes: 19 additions & 14 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
import("@nomiclabs/hardhat-ethers");
import("@nomiclabs/hardhat-waffle");
import dotenv from "dotenv";

const argv = JSON.parse(env("npm_config_argv"));
if (argv.original !== ["hardhat", "test"]) {
require('dotenv').config();
}

import("./tasks/nft");

import { HardhatUserConfig } from "hardhat/config";
import "@nomiclabs/hardhat-ethers";
import "@nomiclabs/hardhat-waffle";
import * as dotenv from "dotenv";
import "./tasks/nft"; // Make sure tasks are correctly imported

// Load environment variables
dotenv.config();

const config: HardhatUserConfig = {
solidity: "0.8.0",
solidity: {
compilers: [
{
version: "0.8.27", // Your main contract version
},
{
version: "0.8.1", // OpenZeppelin dependencies
},
],
},
networks: {
sepolia: {
url: `https://eth-sepolia.alchemyapi.io/v2/${process.env.ALCHEMY_API_KEY}`,
accounts: [process.env.ETH_PRIVATE_KEY],
url: `https://eth-sepolia.g.alchemy.com/v2/${process.env.ALCHEMY_API_KEY}`,
accounts: process.env.ETH_PRIVATE_KEY ? [process.env.ETH_PRIVATE_KEY] : [],
},
},
};
Expand Down
18 changes: 18 additions & 0 deletions ignition/modules/Lock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// This setup uses Hardhat Ignition to manage smart contract deployments.
// Learn more about it at https://hardhat.org/ignition

const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules");

const JAN_1ST_2030 = 1893456000;
const ONE_GWEI = 1_000_000_000n;

module.exports = buildModule("LockModule", (m) => {
const unlockTime = m.getParameter("unlockTime", JAN_1ST_2030);
const lockedAmount = m.getParameter("lockedAmount", ONE_GWEI);

const lock = m.contract("Lock", [unlockTime], {
value: lockedAmount,
});

return { lock };
});
Loading