sol2
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract MyToken {
string public name = "CrowdToken";
string public symbol = "CTK";
uint public totalSupply = 1000000;
mapping(address => uint) public balanceOf;
mapping(address => mapping(address => uint)) public allowance;
constructor() {
balanceOf[msg.sender] = totalSupply;
}
function transfer(address to, uint amount) public returns(bool) {
require(balanceOf[msg.sender] >= amount, "Low Balance");
balanceOf[msg.sender] -= amount;
balanceOf[to] += amount;
return true;
}
function approve(address spender, uint amount) public returns(bool) {
allowance[msg.sender][spender] = amount;
return true;
}
function transferFrom(address from, address to, uint amount) public returns(bool) {
require(balanceOf[from] >= amount, "Low Balance");
require(allowance[from][msg.sender] >= amount, "Not Approved");
allowance[from][msg.sender] -= amount;
balanceOf[from] -= amount;
balanceOf[to] += amount;
return true;
}
}
contract CrowdFund {
MyToken public token;
constructor(address tokenAddress) {
token = MyToken(tokenAddress);
}
struct Campaign {
address creator;
uint goal;
uint pledged;
uint endAt;
bool claimed;
}
uint public count;
mapping(uint => Campaign) public campaigns;
mapping(uint => mapping(address => uint)) public pledgedAmount;
function createCampaign(uint goal, uint duration) public {
count++;
campaigns[count] = Campaign(
msg.sender,
goal,
0,
block.timestamp + duration,
false
);
}
function pledge(uint id, uint amount) public {
Campaign storage c = campaigns[id];
require(block.timestamp < c.endAt, "Campaign ended");
token.transferFrom(msg.sender, address(this), amount);
c.pledged += amount;
pledgedAmount[id][msg.sender] += amount;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract NFTReward {
string public name = "Fan Reward NFT";
string public symbol = "FRNFT";
uint public totalSupply = 0;
mapping(uint => address) public ownerOf;
mapping(address => uint) public balanceOf;
event Transfer(address indexed from, address indexed to, uint indexed tokenId);
function mint(address to) public {
totalSupply++;
uint tokenId = totalSupply;
ownerOf[tokenId] = to;
balanceOf[to]++;
emit Transfer(address(0), to, tokenId);
}
}
Step 1: Open Ganache
Start Ganache and create workspace.
Copy:
RPC Server URL
Example:
HTTP://127.0.0.1:7545
๐น Step 2: Connect MetaMask
Open MetaMask
Add network manually:
Network Name: Ganache
RPC URL: http://127.0.0.1:7545
Chain ID: 1337
Currency: ETH
Import one Ganache account using private key.
๐น Step 3: Open Remix IDE
Go to Remix IDE
Create file:
NFTReward.sol
๐น Step 5: Compile Contract
In Remix:
Solidity Compiler
Version 0.8.x
Click Compile NFTReward.sol
๐น Step 6: Deploy Contract
Go to Deploy & Run Transactions
Select:
Environment = Injected Provider - MetaMask
Choose MetaMask account.
Click Deploy
Confirm transaction.
๐น Step 7: Mint NFT Reward
After deployment:
In deployed contract:
Call mint()
Enter wallet address:
0x123....
Click:
mint(address)
NFT created.
๐น Step 8: Check Ownership
Use:
ownerOf(1)
Returns owner address.
Use:
balanceOf(address)
Shows NFTs owned.
๐น Practical Demo Example
Gaming Rewards
Player clears level โ Admin calls:
mint(player address)
Player gets NFT trophy.
Fan Engagement
Fan buys concert ticket โ NFT pass issued.
๐น Output for Viva
NFT Token ID 1 minted successfully.
Owner = 0xAbc...
Balance = 1
๐น Viva Questions
What is NFT?
Non Fungible Token = unique digital asset.
Why NFT for fans?
Collectibles, tickets, rewards.
Why blockchain?
Ownership proof + secure transfer.
Step 1: Open Remix IDE
Go to:
Remix IDE
Create a new file:
EnglishAuction.sol
Step 2: Paste This Smart Contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IERC721 {
function transferFrom(
address from,
address to,
uint tokenId
) external;
}
contract EnglishAuction {
address payable public seller;
IERC721 public nft;
uint public nftId;
uint public endAt;
bool public started;
bool public ended;
address public highestBidder;
uint public highestBid;
mapping(address => uint) public bids;
constructor(address _nft, uint _nftId) {
seller = payable(msg.sender);
nft = IERC721(_nft);
nftId = _nftId;
}
// Start Auction
function startAuction() public {
require(msg.sender == seller, "Not seller");
require(!started, "Already started");
started = true;
// Auction for 7 days
endAt = block.timestamp + 7 days;
// Transfer NFT to contract
nft.transferFrom(seller, address(this), nftId);
}
// Place Bid
function bid() public payable {
require(started, "Auction not started");
require(block.timestamp < endAt, "Auction ended");
require(msg.value > highestBid, "Bid too low");
// Store previous highest bid
if (highestBidder != address(0)) {
bids[highestBidder] += highestBid;
}
highestBidder = msg.sender;
highestBid = msg.value;
}
// Withdraw previous bid
function withdraw() public {
uint bal = bids[msg.sender];
require(bal > 0, "No balance");
bids[msg.sender] = 0;
payable(msg.sender).transfer(bal);
}
// End Auction
function endAuction() public {
require(started, "Not started");
require(block.timestamp >= endAt, "Auction not ended");
require(!ended, "Already ended");
ended = true;
if (highestBidder != address(0)) {
// Transfer NFT to winner
nft.transferFrom(
address(this),
highestBidder,
nftId
);
// Send ETH to seller
seller.transfer(highestBid);
} else {
// Return NFT if no bids
nft.transferFrom(
address(this),
seller,
nftId
);
}
}
}
Step 3: You Also Need an NFT Contract
Create another file:
MyNFT.sol
Paste this code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract MyNFT {
string public name = "MyNFT";
string public symbol = "MNFT";
uint public tokenCount;
mapping(uint => address) public ownerOf;
function mint() public {
tokenCount++;
ownerOf[tokenCount] = msg.sender;
}
function transferFrom(
address from,
address to,
uint tokenId
) public {
require(ownerOf[tokenId] == from,
"Not owner");
ownerOf[tokenId] = to;
}
}
Step 4: Compile Contracts
In Remix:
Compile MyNFT.sol
Solidity version โ 0.8.x
Click Compile
Then compile:
EnglishAuction.sol
Step 5: Deploy NFT Contract
Go to:
Deploy & Run Transactions
Environment
Choose:
Injected Provider - MetaMask
OR
Ganache Provider
Deploy:
MyNFT
Step 6: Mint NFT
After deployment:
Click:
mint()
This creates NFT token ID = 1.
Step 7: Deploy Auction Contract
Deploy:
EnglishAuction
Constructor parameters:
_nft
Paste deployed NFT contract address.
_nftId
1
Then click:
Deploy
Step 8: Start Auction
From seller account:
Click:
startAuction()
This:
starts auction
locks NFT inside contract
starts 7-day timer
Step 9: Place Bids
Switch MetaMask/Ganache accounts.
Use:
bid()
Before clicking bid:
In VALUE field enter ETH amount:
Example:
1
Next bidder enters:
2
Then:
3
Each new bid must be higher.
Step 10: Withdraw Old Bid
Old bidder can recover ETH.
Example:
Account2 bid 1 ETH
Account3 bid 2 ETH
Now Account2 can click:
withdraw()
to get 1 ETH back.
Step 11: End Auction
After 7 days:
Click:
endAuction()
Result:
Highest bidder gets NFT
Seller gets ETH
If You Donโt Want to Wait 7 Days
For practical/demo purposes, change this line:
endAt = block.timestamp + 7 days;
to:
endAt = block.timestamp + 2 minutes;
Then:
deploy again
test quickly
Full Practical Flow
Seller
Deploy NFT
Mint NFT
Deploy Auction
Start Auction
Bidder 1
Bid 1 ETH
Bidder 2
Bid 2 ETH
Bidder 1
Withdraw old bid
Seller
End Auction
Result
Bidder 2 owns NFT
Seller receives 2 ETH
Viva Explanation (Easy Words)
What is English Auction?
An auction where:
people continuously place higher bids
highest bidder wins
What is NFT?
NFT means Non-Fungible Token.
It represents ownership of a digital item.
Why use Smart Contract?
Smart contract:
automatically handles bidding
securely stores ETH
transfers NFT to winner
prevents cheating
What does withdraw() do?
It allows old bidders to safely take back their ETH.
What does mapping(address => uint) store?
It stores refundable balances of bidders.
What is msg.value?
ETH sent with transaction.
What is block.timestamp?
Current blockchain time.
Used for auction timer.
Expected Output
You should see:
NFT owner changes to highest bidder
Seller ETH balance increases
Auction ends successfully
Previous bidders can withdraw ETH
That is the correct output for this practical.